反应本机,更改子类的值

时间:2020-10-07 05:22:10

标签: javascript reactjs react-native

我制作了两个屏幕,第一个主屏幕和第二个用于编辑屏幕。我想从编辑屏幕更新值,但是当我单击保存按钮时,它显示错误setState(...): takes an object of state variables to update or a function which returns an object of state variables并显示空白主屏幕。有人可以告诉我如何从子类中更新价值吗?下面是我的代码,请帮助

home.js

class Home extends Component {
  state = {
    modal: false,
    editMode: false.
    post: [
      {
        key: "1",
        title: "A Good Boi",
        des: "He's a good boi and every one know it.",
        image: require("../assets/dog.jpg"),
      },
      {
        key: "2",
        title: "John Cena",
        des: "As you can see, You can't see me!",
        image: require("../assets/cena.jpg"),
      },
    ],
  };

  addPost = (posts) => {
    posts.key = Math.random().toString();
    this.setState((prevState) => {
      return {
        post: [...prevState.post, posts],
        modal: false,
      };
    });
  };

  onEdit = (data) => {
    this.setState({ post: { title: data }, editMode: false });
  };

 

  render() {
    if (this.state.editMode)
      return <EditScreen item={item} onEdit={this.onEdit} />;
    return (
      <Screen style={styles.screen}>
        <Modal visible={this.state.modal} animationType="slide">
          <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
            <View style={styles.modalContainer}>
            
              <AddPost addPost={this.addPost} />
            </View>
          </TouchableWithoutFeedback>
        </Modal>
        <FlatList
          data={this.state.post}
          renderItem={({ item }) => (
            <>
            
              <TouchableOpacity
                activeOpacity={0.7}
                onPress={() => this.setState({ editMode: true })}
                style={styles.Edit}
              >
                <MaterialCommunityIcons
                  name="playlist-edit"
                  color="green"
                  size={35}
                />
              </TouchableOpacity>
              <Card>
                <Image style={styles.image} source={item.image} />
                <View style={styles.detailContainer}>
                  <Text style={styles.title} numberOfLines={1}>
                    {item.title}
                  </Text>
                  <Text style={styles.subTitle} numberOfLines={2}>
                    {item.des}
                  </Text>
                </View>
              </Card>
            </>
          )}
        />
      </Screen>

Edit.js

<KeyboardAvoidingView
        behavior="position"
        keyboardVerticalOffset={Platform.OS === "ios" ? 0 : 100}
      >
        <Image style={styles.image} source={item.item} />
        <View style={styles.detailContainer}>
          <AppTextInput value={item.title} />
          <AppTextInput value={item.des} />
        </View>
        <AppButton
          text="Save"
          onPress={() => {
            onEdit(this.state);
            this.props.navigation.goBack("Home");
          }}
        />
      </KeyboardAvoidingView>

我也收到警告

This can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.

1 个答案:

答案 0 :(得分:1)

看来ListDetails实际上不是Home的子代。如果可以的话,您可以将onEdit函数作为道具传递下来。

您不应将其作为导航参数传递,因为当您离开Home页面时,它将被卸载,并且您将无法更新状态。

一种实现所需目标的方法是使用Context API为应用程序状态设置存储。

查看以下内容:https://reactjs.org/docs/context.html

编辑,无上下文:

您需要将ListDetails组件中的Home组件作为子组件移动。您可以将值保持在状态以检查您是否处于编辑模式。可能是这样的:

class Home extends Component {
  state = {
    selectedItem: undefined,
    modal: false,
    post: [
      {
        key: "1",
        title: "A Good Boi",
        des: "He's a good boi and every one know it.",
        image: require("../assets/dog.jpg"),
      },
      {
        key: "2",
        title: "John Cena",
        des: "As you can see, You can't see me!",
        image: require("../assets/cena.jpg"),
      },
    ],
  };

  addPost = (posts) => {
    posts.key = Math.random().toString();
    this.setState((prevState) => {
      return {
        post: [...prevState.post, posts],
        modal: false,
      };
    });
  };

  onEdit = (data) => {
    this.setState({ post: { title: data }, editMode: false, selectedItem: undefined });
  };

  render() {
    const { editMode, selectedItem } = this.state;

    if (editMode && selectedItem) return <ListDetails item={selectedItem} onEdit={onEdit} />

    return (
      <Screen style={styles.screen}>
        <Modal visible={this.state.modal} animationType="slide">
          <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
            <View style={styles.modalContainer}>
              <AddPost addPost={this.addPost} />
            </View>
          </TouchableWithoutFeedback>
        </Modal>
        <FlatList
          data={this.state.post}
          renderItem={({ item }) => (
            <>
              <TouchableOpacity
                activeOpacity={0.7}
                onPress={() => this.setState({ editMode: true, selectedItem: item })}
                style={styles.Edit}
              >
                <MaterialCommunityIcons
                  name="playlist-edit"
                  color="green"
                  size={35}
                />
              </TouchableOpacity>
              <Card>
                <Image style={styles.image} source={item.image} />
                <View style={styles.detailContainer}>
                  <Text style={styles.title} numberOfLines={1}>
                    {item.title}
                  </Text>
                  <Text style={styles.subTitle} numberOfLines={2}>
                    {item.des}
                  </Text>
                </View>
              </Card>
            </>