【问题标题】:React setState doesnt update the componentReact setState 不更新组件
【发布时间】:2021-02-25 09:43:06
【问题描述】:

我不知道为什么刷新状态后我的 react 应用程序不会更新。 我正在显示一个表格,可以通过单击突出显示其中的行。 在触摸屏上向下滑动时,它应该重新加载。动画正在显示,但表格没有更新,突出显示仍然存在。

我提供了一个小代码示例。如果这篇文章需要更多代码或信息,请随时发表评论。

提前致谢。

const dummyKonten = [
          { id: 1,
          icon: 'a',
          name: 'Sparkasse',
          isSelect: false },
          { id: 3,
          icon: 'b',
          name: 'Volksbank',
          isSelect: false }]

constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
      isRefreshing: false,
      konten: [...dummyKonten],
      updatedKonten: [...dummyKonten],
    };
  }

onRefresh = () => {
        const reset = [...this.state.konten];
        
        this.setState(
          {
            isRefreshing: true,
          }
        );
    
        wait(2000).then(() => {
        this.setState(
          { isRefreshing: false, 
          updatedKonten: reset } )}
        );
      }

selectItem = (item) => {
    item.isSelect = !item.isSelect;
    
    const index = this.state.updatedKonten.findIndex(
      indexItem => indexItem.id === item.id
    );
    
    const newKonten = [...this.state.updatedKonten];
    newKonten[index] = item;
    this.setState(
      {
        updatedKonten: newKonten,
      }
    );
  };

render(){ 
      return(
        <SafeAreaView style={styles.view}>
          <StatusBar barStyle="dark-content" />
          <View style={styles.viewBody}>
          <FlatList
            data={this.state.updatedKonten}
            extraData={this.state.updatedKonten}
            renderItem={this.renderKonto}
            ItemSeparatorComponent={this.flatListItemSeparator}
            refreshControl={
              <RefreshControl colors={["#5797C5"]} refreshing={this.state.isRefreshing} onRefresh={this.onRefresh} />}
            showsHorizontalScrollIndicator={false}
            keyExtractor={item => item.id.toString()}
          />
          </View>
          <HomeButton navigation={this.props.navigation} />
      </SafeAreaView>
      );
  }

【问题讨论】:

    标签: reactjs react-native react-native-flatlist


    【解决方案1】:

    啊,我想我知道现在可能发生什么了。你真的不应该需要使用 JSON 来序列化/反序列化你的数据来克隆它。您应该避免在生产代码中使用这种模式。

    我认为问题在于您的 selectItem 处理程序中的状态突变。如果我的猜测是正确的,您的项目渲染器this.renderKonto 可能使用了selectItem 回调。

    我怀疑您正在从state.updatedKonten 状态数组传递对item 元素的引用,对其进行变异,然后将其保存回数组中。问题是即使 state.updatedKonten 是一个新的数组引用,state.updatedKonten[index] 处的项目与之前的旧 item 对象引用相同。

    selectItem = (item) => {
      item.isSelect = !item.isSelect; // <-- (1) item mutation
    
      const index = this.state.updatedKonten.findIndex(
        indexItem => indexItem.id === item.id
      );
    
      const newKonten = [...this.state.updatedKonten];
      newKonten[index] = item; // <-- (2) 
      this.setState({
        updatedKonten: newKonten,
      });
    };
    

    由于这个 React 可能会放弃重新渲染项目,因为它们的对象引用没有改变。

    解决方案

    基本上更新selectItem 处理程序以使用功能状态更新和浅拷贝状态以及任何正在更新的嵌套状态。可以将前一个状态映射到下一个状态数组,当item id匹配时,浅拷贝item并更新isSelect属性。

    selectItem = (item) => {
      this.setState((prevState) => ({
        updatedKonten: prevState.updatedKonten.map((itemEl) =>
          itemEl.id === item.id
            ? {
                ...itemEl,
                isSelect: !itemEl.isSelect
              }
            : itemEl
        )
      }));
    };
    

    【讨论】:

    • 我明白了。那是一个更好的解决方案。谢谢
    【解决方案2】:

    好的,我明白了。

    问题是我在该州克隆数组的方式。 对于这个问题,需要数组的深拷贝。 所以我改变了

    constructor(props) {
        super(props);
        this.state = {
          isLoading: true,
          isRefreshing: false,
          konten: [...dummyKonten],
          updatedKonten: [...dummyKonten],
        };
      }
    

    到:

    constructor(props) {
        super(props);
        this.state = {
          isLoading: true,
          isRefreshing: false,
          konten: JSON.parse(JSON.stringify(dummyKonten)),
          updatedKonten: JSON.parse(JSON.stringify(dummyKonten)),
        };
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-30
      • 1970-01-01
      • 2019-06-14
      • 2021-04-28
      • 2021-01-12
      • 2014-04-19
      • 2022-11-22
      • 1970-01-01
      相关资源
      最近更新 更多