繁体   English   中英

如何正确更新/重新渲染不是子级React Native的组件?

[英]How to properly update/re-render a component that is not a child React Native?

我正在使用反应导航。 更具体地说,我将一个materialTabNavigator嵌套在抽屉导航器内部。 每个选项卡本身就是一个stackNavigator。 我在homeScreen中有一个按钮,可导航至makePost.js。 我在那里接收信息,并使用一个简单的包装将其存储到异步存储中。

在Posts.js中,有一个FlatList将每个帖子显示为一个组件。 从异步存储发出请求后,最初会正确设置FlatList的数据。 问题在于,只有在首次打开应用程序时才会发生这种情况。 我尝试了许多不同的方法来解决此问题。 到目前为止,我发现的唯一方法是在Posts.js的ComponentDidUpdate()中连续setState。 显然,这是有问题的,因为它会不断重新渲染。 我可以设置一个标志来阻止正在渲染,但是它不会再次重新渲染。

最终,我想发生的事情是,当我点击用户时,完成输入他们的信息并准备发布的内容时,他们点击了makePost.js中的按钮,并且Posts.js的FlatList中的数据已更新。 。

我尝试使用导航传递参数,但不起作用,参数会丢失,可能是因为嵌套的导航器。

我确实可以在完成此操作的正确方法上使用一些指导。

(导航器;不确定为什么要强制执行一行)

--- drawer --tabNav -home homeScreen.js makePost.js
-posts posts.js -messages --drawer1 --drawer2

//Posts.js
export default class Posts extends React.Component {
  state = { 
    rows: [
      {id: 0, text: "dog"},
    ],
  }

  componentDidMount() {
    this.loadState();
  }

  loadState = () => {
    var value = store.get('posts').then((res => {
        if (res === null) {
          res = [{id: 0, text: "default"}]
        } else {
          res = res 
        }
        this.setState({rows: res})
    }))
  }

  componentDidUpdate() {
    this.loadState();
  }

  renderItem = ({item}) => {
    return (
      <BoardTab style={styles.row} />
    )} 

  render() {
    return (
      <View style={styles.view}>
        <FlatList
          ListFooterComponent={this.renderFooter}
          style={styles.container}
          data={this.state.rows}
          renderItem={this.renderItem}
          keyExtractor={extractKey}
         >
        </FlatList>
        <BoardScreenFooter />
      </View>
    );
  }

而Posts.js按钮如下所示:

        <TouchableOpacity 
            onPress={ () => {
            this._onPressButton
            this.storeFunc(this.state.newPost)
            const retval = this.state.rows

            this.props.navigation.navigate('Board', 
            {rowsID: retval});

            }
          }>
          <Icon
            reverse
            name='md-camera'
            type='ionicon'
            color='green'
          size={12}
          />
        </TouchableOpacity>  



  storeFunc(newObj) {
    newObj.id = newObj.id + 1
    store.push('posts', newObj)
    store.get('posts').then((res) => {
      this.setState({rows: res})
    })
  }

很快,我会说:使用Redux。 它使您可以在应用程序中拥有全局状态,这意味着您可以在任何地方访问该状态(也可以在任何地方设置它们)。打开应用程序时,您会将数据从AsyncStore获取到Redux存储中。 您将聆听redux状态(组件中将是props)并显示您的列表。 在其他标签中修改列表时,您需要做两件事:

  1. 将新数据存储在AsyncStorage中
  2. 更新redux存储中的状态。 由于Posts.js将在redux商店(作为道具)进行监听,因此每次您的数据更改时,它将重新呈现

在导航到React-Navigation屏幕视图时,一种简单的方法可以重新渲染它:

一切归功于Andrei Pfeiffer,2018年7月,在他的文章中:《 React Navigation v2中的Handle Tab更改》 https://itnext.io/handle-tab-changes-in-react-navigation-v2-faeadc2f2ffe

如果以上链接失效,我将在此重申。

只需使用所需的侦听器道具将NavigationEvents组件添加到渲染函数即可:

  render() {
return (
      <View style={styles.view}>
      <NavigationEvents
          onWillFocus={payload => {
            console.log("will focus", payload);
            this.loadState();
          }}
        />
        <FlatList
          ListFooterComponent={this.renderFooter}
          style={styles.container}
          data={this.state.rows}
          renderItem={this.renderItem}
          keyExtractor={extractKey}
        >
        </FlatList>
        <PostScreenFooter />
      </View>
    );
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM