【问题标题】:React Native Component not updating with state changesReact Native Component 不会随着状态变化而更新
【发布时间】:2019-09-13 20:01:19
【问题描述】:

所以我做了很多 React Web 开发。不是很多 React Native 但这对我来说真的很疯狂。我有这个组件

相关代码

 componentDidMount() 

    axios.get(URL + 'ATL')
    .then(function (response) {
      // handle success
      console.log("AXRES1::",response);
        this.setState({
          rows: response.data,
          loading: false,
        })
    }.bind(this))
    .catch(function (error) {
      // handle error
      console.log("AXRES2::",error.message);
       this.setState({ loading: false })
    }.bind(this))
    .finally(function () {
      console.log("AXRES3::");
      this.setState({ loading: false })
    }.bind(this));

  }

render() {
    const placeholder = {
      label: 'Select SSA Region...',
      value: this.state.region,
      color: '#093387',
    };
    console.log("ROWS::",this.state.rows.length)
    return (
      <View style={{ flex: 1 }}>
        <View style={{ flex: 1 }}>
          <Swiper
            from={1}
            minDistanceForAction={0.1}
            controlsProps={{
              dotsTouchable: true,
              prevPos: 'bottom-left',
              nextPos: 'bottom-right',
              nextTitle: '',
              prevTitle: '',
              nextTitleStyle: { color: '#2298f2', fontSize: 50, fontWeight: '500' },
              prevTitleStyle: { color: '#2298f2', fontSize: 50, fontWeight: '500' }
            }}
          >
            <View style={{ flex: 1 }}>
              <Title style={styles.header}><Text h1>SSA Regional Locator App</Text></Title>
              <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
                <Image
                  style={{}}
                  source={Images.USM}
                />
              </View>
            </View>

            <View style={{ flex: 1 }}>
              <Title style={styles.header}>Choose a Region</Title>
              <Title style={styles.header}>Find an Office {this.state.rows.length}</Title>
              <RNPickerSelect
                placeholder={placeholder}
                items={regions}
                onValueChange={value => {
                  console.log("VALUE::",value);
                  this.setState({
                    region: value,
                  });
                }}
                style={pickerSelectStyles}
                value={this.state.region}
                useNativeAndroidPickerStyle={false}
              />
              <DataTable>
                <DataTable.Header style={headerStyles}>
                  <DataTable.Title><Subheading>RO Name</Subheading></DataTable.Title>
                  <DataTable.Title><Subheading>Email</Subheading></DataTable.Title>
                  <DataTable.Title numeric><Subheading>Business Line</Subheading></DataTable.Title>
                  <DataTable.Title numeric><Subheading>State</Subheading></DataTable.Title>
                </DataTable.Header>
                {this.state.rows.map((row, i) => {
                  const img = "../images/flags/" + row.stateCode + ".png"
                  // console.log("ROW2::", img);
                  return (
                    <DataTable.Row key={i} style={rowStyles}>
                      <DataTable.Cell style={rowStyles}>{row.name}</DataTable.Cell>
                      <DataTable.Cell style={rowStyles}>{row.email}</DataTable.Cell>
                      <DataTable.Cell style={rowStyles} numeric>{row.businessLine}</DataTable.Cell>
                      <DataTable.Cell style={rowStyles} numeric>
                        <Image
                          style={{ width: 16, height: 12 }}
                          source={Images.flags[row.stateCode]}
                        />
                      </DataTable.Cell>
                    </DataTable.Row>
                  )
                })}
                <DataTable.Pagination
                  page={1}
                  numberOfPages={3}
                  onPageChange={(page) => { console.log(page); }}
                  label="1-2 of 6"
                />
              </DataTable>
            </View>
          </Swiper>
        </View>
      </View>
    );
  };
}

我正在成功更新我的行。我可以查看我的控制台日志,这些日志表明我的渲染和返回之间的控制台日志语句中的值从 1 到 652 行的变化。

2019-09-13 15:54:10.109 2708-2976/com.regionlocator I/ReactNativeJS: 'ROWS::', 1

2019-09-13 15:54:12.613 2708-2976/com.regionlocator I/ReactNativeJS: 'ROWS::', 652

从我在这里检查的 fetch 中数据看起来也是正确的

console.log("AXRES1::",response)

这是我期待的对象数组。但我的数据表永远不会改变。也没有错误。我错过了什么。我很困惑。

****还有一个重要提示

我应该在我最初发布时提到,如果我取消注释 console.log("ROW2::", img); 我会看到那些反映我获取的新数据的控制台日志。我发现这真的很奇怪,这不是在 android 模拟器中呈现新的数据表项,因为显然这些项正在被映射。在本机反应和模拟器中渲染有什么特别之处,也许我不知道。我觉得这肯定会出现在 React Web 应用程序中。

【问题讨论】:

  • 确实,您的父组件正在重新渲染,因为您看到了 'ROWS::' 日志,但是 DataTable 子组件实际上正在重新渲染吗?你有一个 "console.log("ROW2::", img);"评论中的声明;当状态改变时,你真的看到这些被记录了吗?在这种情况下,DataTable 可能与 FlatLlist 类似,不会触发重新渲染。
  • 是的,当我取消注释 console.log("ROW2::", img); 时我应该提到我看到这些控制台日志反映了我获取的新数据。我觉得这不是在模拟器中渲染真的很奇怪,因为很明显我正在获取控制台日志,代码正在运行似乎它应该正在渲染。
  • 这是一个完美的例子,为什么使用数组索引作为反应键不起作用,对象更新但键保持不变,因此反应在重新渲染时保释。尝试使用元素的唯一键,例如 key={row.email}key={row.name},只要可以在数据更新之间提供新的唯一键。
  • 我正在使用索引,因为我无法保证数组中的另一个唯一值。也就是说,我尝试了这个&lt;DataTable.Row key={generateKey(row.name)} style={rowStyles}&gt;,其中 generateKey 正在使用 DateTime getTime,但它仍然没有在模拟器中用行呈现表格。
  • 我看到您的代码中仍有示例中的 DataTable.Pagination。您是否尝试删除它?此外,最好缩小您的代码并从一个最小的示例开始。类似于snack.expo.io/S1otnpjIr,它使用组件的状态来更新表行。您的样式表也可能是相关的,尤其是 rowStyles。最好将此添加到您的帖子中。

标签: reactjs react-native fetch react-native-android


【解决方案1】:

我删除了Swiper 组件并且它起作用了。我确实在Swiper 组件中看到了其他一些带有 setState 问题的帖子。也许我是如何使用它的,不确定。这只是一个证明,所以我试着快速把所有东西放在一起。无论哪种方式,我只是想如果有人回到这里,我会发帖。

【讨论】:

    猜你喜欢
    • 2020-09-10
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 2016-10-27
    相关资源
    最近更新 更多