Реагировать данные Native Pass между представлениями сестры

Я разрабатываю простое приложение todo-list с помощью React Native, моя проблема в следующем: у меня есть NavigatorIOS в корне моего проекта, с компонентом, содержащим ListView в качестве начального маршрута, и кнопкой панели навигации что приводит к представлению создания задачи.

Как только новая задача была создана, представление открывается, чтобы отображался ListView. Я пытаюсь добавить новую созданную задачу в этот ListView (его источник данных содержится в состоянии компонента).

Как выполнить такую ​​операцию, какая хорошая практика? Я бы использовал делегат в чистом родном приложении, но здесь оба представления обрабатываются экземпляром NavigatorIOS.

index.ios.js

addTask() {
    console.log("Test");
},

render() {
        return (
            <React.NavigatorIOS
                ref="nav"
                style={styles.container}
                tintColor="#ED6063"
                initialRoute={{
                    title: "Tasks",
                    component: TasksList,
                    rightButtonTitle: 'Add',
                    onRightButtonPress: () => {
                        this.refs.nav.navigator.push({
                            title: "New task",
                            component: NewTask,
                            passProps: {
                                onTaskAdded: this.addTask
                            },
                            leftButtonTitle: "Cancel"
                        });
                    }
                }}/>
        );
    }

NewTask.js

taskAdded() {
console.log("Added: " + this.state.title + " - " + this.state.description);
this.props.onTaskAdded({
    title: this.state.title,
    description: this.state.description
});
this.props.navigator.pop();
}

TasksList.js

var dataSource = new ListView.DataSource({
    rowHasChanged: (r1, r2) => r1 !== r2
});
this.state = {
    dataSource: dataSource.cloneWithRows(data)
};

Здесь вы можете найти полный исходный код.

Ответы

Ответ 1

Документация React-Native содержит краткий раздел о подходах к общении между компонентами.

Когда вы пытаетесь сделать что-то более сложное, чем родительское отношение parent- > child или child- > , существует несколько вариантов:

  • Шаблон диспетчера. Для истинной связи между братьями и сестрами (т.е. Когда два брата и сестры совместно используют родителя через композицию), вы можете иметь родительское управление в состоянии. Например, у вас может быть виджет <MyConsole> с <TextInput> и <ListView>, содержащий предыдущие входы пользователя, оба являются дочерними элементами виджета <Console>.

    • Здесь <Console> может выступать в качестве менеджера. Когда значение <TextInput> изменит его значение, вы можете использовать событие onChangeText, чтобы передать новое значение до родительского компонента <MyConsole>, который затем обновляет свое состояние и передает его своим дочерним элементам.
  • Шаблон события (публикация-подписка). Помните, что компоненты - это просто объекты, поэтому вы можете использовать объектно-ориентированные подходы к общению между компонентами. В документах React указано, что:

    Для связи между двумя компонентами, не имеющими отношения родитель-потомок, вы можете настроить свою собственную глобальную систему событий. Подпишитесь на события в компонентеDidMount(), отмените подписку на componentWillUnmount() и вызовите setState(), когда вы получаете событие.

    • Здесь вы можете использовать обычную библиотеку публикации-подписки, такую ​​как pubsub.js, чтобы при изменении одного компонента она только публиковала изменения и другие связанные компоненты могут прослушивать событие и обновлять себя. Это может быть очень эффективным подходом для небольших приложений.
  • Образец потока. Одним из недостатков чистой системы публикации/подписания является то, что отслеживать состояние становится сложно. Например, если у вас есть 2 компонента (например, EditTitle, EditBody), которые могут обновлять некоторые состояния, такие как сообщение электронной почты, тогда чистая eventing-система заканчивает передачу разных версий состояния, вокруг которых может возникнуть беспорядок с конфликтами, потому что нет "единого версии правды". Здесь происходит React подход к потоку. С потоком компоненты обновляют хранилище данных, которое отвечает за обновление и согласование данных (например, EmailDataStore), и затем магазин уведомляет компоненты обновленного состояния.

    • Итак, в вашем примере представление задачи выдало бы обновление (например, через публикацию или прямой вызов функции) в TasksDataStore, которое затем могло бы опубликовать событие, подобное tasks-updated его подписчикам. Панель задач и панель результатов подписываются на хранилище данных.

При настройке подписки лучше добавлять подписки после монтирования компонентов и, безусловно, удалять их перед отключением компонента (в противном случае у вас много сиротских подписчиков).

Ответ 2

Вы должны переписать свою функцию constructor, чтобы получить данные динамическим способом. Затем, когда страница перезагружается, она получит правильные данные, которые включают новую задачу. Здесь вы получаете данные из статического массива, которые не меняются.

Сохранить список задач в локальном файле или Firebase и прочитать при построении.