简体   繁体   English

React Native —在Child事件处理程序更新Parent的状态后,Child中的.Map()项不会重新呈现

[英]React Native — .Map() items in Child won't rerender after Child event handler updates Parent's state

In my project, while looping through a datafile with the .map() function, I'm passing down a function ( updatestate ) from the Parent Component, App , to the Child, Main , that allows the Child to call .setState() and append to the array in the Parent state. 在我的项目中,使用.map()函数循环访问数据文件时,我将一个函数( updatestate )从父组件App传递给子Main ,该子允许Main调用.setState()并以Parent状态附加到数组。

But, when I call this function to set Parent's state, the mapped section -- {contents} -- won't rerender unless I tap the screen again. 但是,当我调用此函数设置Parent的状态时, 除非再次点击屏幕,否则 映射的部分 {contents} 不会重新渲染。

Any ideas? 有任何想法吗? Am I missing some binding or need to do some componentDidMount or anything? 我是否缺少绑定或需要执行一些componentDidMount或其他操作? I've tried adding this.forceUpdate() inside the eventHandler but the **mapped {contents} section ** still won't render automatically. 我已经尝试在eventHandler中添加this.forceUpdate() ,但是**映射的{contents}部分**仍不会自动呈现。

const RootStack = StackNavigator(
  {
    Main: {
      screen: Main}
  }
);

export default class App extends Component<{}> {
    constructor(props) {
      super(props);
      this.state = {
        favoritesList: []
      };
    }

  updateArr=(itemname, url)=>{this.setState({ favoritesList: [...this.state.favoritesList, {"item_name":itemname, "url":url}]})};

  render() {
      return <RootStack screenProps={{appstate: this.state,
                                    updatestate: this.updateArr}}
      />;
    }
  }

class Main extends React.Component {

  render() {
    var updatestate = this.props.screenProps.updatestate;

    //collection is the data (local JSON) i'm looping thru via .map in Main Component

    const contents = collection.map((item, index) => {
        return (
            <Card key={index}
                  onSwipedRight={() => {updatestate(item.item_name,item.url)}}
            >
              <View> //THIS and anything after <Card> doesn't render for the next card automatically if I do 'onSwipedRight'
                <Image
                    source={{uri: item.url}} />
               </View>
            </Card>
        )
      },this);

      return (
      <View>
            <CardStack>

              {contents} //THIS IS THE PART THAT WON'T AUTO-RERENDER AFTER THE EVENT HANDLER THAT SETS THE PARENT'S STATE

            </CardStack>
      </View>
        );
    }
}

To make sure it's not an issue with the event handler, I added in a function that doesn't set the state of the parent, and had <Card> call that on the event handler -- it works perfectly and the child component <Card> renders perfectly. 为确保事件处理程序没有问题,我添加了一个未设置父级状态的函数,并在事件处理程序上调用了<Card> -效果很好,子组件<Card>完美呈现。 It seems that it's the updatestate function passed down from the parent to the child that acts to call .setState() upstream that for some reason is causing the Child to not render/not finish rendering the mapped {contents} after the event handler. 似乎是从父级传递到子级的updatestate函数在上游调用了.setState() ,由于某种原因,该事件导致子级在事件处理程序之后未呈现/未完成呈现映射的{contents}

class Main extends React.Component {
  render() {

    var updatestate = this.props.screenProps.updatestate;

    var newfunc = (a, b) => {console.log('a:', a, 'b:', b)};

      const contents = collection.map((item, index) => {
        return (
            <Card key={index}
                  newfunc(item.item_name,item.item_name);}}
                  // onSwipedRight={() => {updatestate(item.item_name,item.url); }}
                  >

Try rewriting your setState like so 尝试像这样重写您的setState

 import { InteractionManager } from "react-native"; updateArr = (itemname, url) => { InteractionManager.runAfterInteractions(() => { this.setState( prevState => ({ favoritesList: [...prevState.favoritesList, { "item_name":itemname, "url":url } ] }); }); } // add this line to your parent component constructor() this.updateArr = this.updateArr.bind(this); 

In addition I suggest you change your React.Component to React.PureComponent instead it will handle the shallow equal of your state changes for you and increate performance. 另外,我建议您将React.Component更改为React.PureComponent,它将为您处理状态改变的浅薄部分,并提高性能。 for reference React.Component vs React.PureComponent 供参考React.Component与React.PureComponent

Try not using index as key . 尝试不要将index用作key Meaningful key values help the engine figure out what needs to be redrawn. 有意义的键值可帮助引擎确定需要重绘的内容。

In your case, I'd suggest key={item.url} as a first go. 对于您的情况,我建议您先使用key={item.url}

https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318 https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

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

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