React Native - Child中的.Map()项目在Child事件处理程序更新之后不会重新呈现父母的状态

时间:2018-02-26 00:01:08

标签: javascript reactjs react-native react-component

在我的项目中,在使用.map()函数循环数据文件时,我将一个函数(updatestate)从父组件App传递给子项Main,允许Child调用.setState()并附加到Parent状态的数组。

但是,当我调用此函数设置父级状态时,映射部分 - {contents} - 赢了&# 39;除非我再次点击屏幕,否则不要重新播放。

有什么想法吗?我错过了一些绑定或需要做一些componentDidMount或其他什么?我尝试在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>
        );
    }
}

为了确保它不是事件处理程序的问题,我添加了一个不设置父级状态的函数,并在事件处理程序上调用了<Card> - 它完美地工作,子组件<Card>完美呈现。它似乎是从父级传递给子级的updatestate函数,该函数用于调用.setState()上游,由于某种原因导致Child无法渲染/不完成渲染<在事件处理程序之后强>映射{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); }}
                  >

1 个答案:

答案 0 :(得分:1)

尝试重写你的setState

&#13;
&#13;
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);
&#13;
&#13;
&#13;

此外,我建议您将React.Component更改为React.PureComponent,而不是为您处理浅层等于状态更改并提高性能。 供参考React.Component vs React.PureComponent