【问题标题】:React Native / Redux - Can only update a mounted or mounting componentReact Native / Redux - 只能更新已安装或已安装的组件
【发布时间】:2018-04-12 11:19:32
【问题描述】:

我只是从服务器获取项目并将它们显示在列表组件中。组件结构是这样的

ServiceScreen(parent) -> ServicesList(child- used inside ServiceScreen) -> ServiceItem (child used inside ServicesList)

一切正常,它显示获取的服务,但它给了我以下警告

警告:只能更新已安装或已安装的组件。这通常 表示您在一个 未安装的组件。这是一个无操作。请检查代码 YellowBox 组件。

代码如下

ServiceScreen.js

constructor(props) {
    super(props);
    this.props.actions.fetchServices();
  }
    render() {
        const { isFetching } = this.props;
        return (
          <View style={styles.container}>
            <ServicesList services={this.props.services} navigation={this.props.navigation} />
          </View>
        );
      }

ServicesList.js

render() {
    return (
      <View style={{ flex: 1 }}>
        <FlatList
            data={this.props.services}            
            renderItem={
                ({ item }) => 
                <ServiceItem navigation={this.props.navigation} item={item} />
            }
        />
      </View>
    );
  }

ServiceItem.js

render() {
        const { item } = this.props;
        return (
            <TouchableOpacity onPress={this.singleService}>
                <Text>{item.service_name}</Text>
            </TouchableOpacity>
        );
    }

当我使用 redux 进行状态管理时,我已经映射了服务 状态到我的 ServiceScreen 组件。我把它传给孩子 组件。

【问题讨论】:

  • 您在哪里调用获取数据的操作?请发布整个 ServiceScreen 组件和您执行抓取的操作。
  • 我在构造函数中调度操作来获取服务。我已经更新了这个问题。 action 成功调度并更新了 redux store 中的状态

标签: javascript reactjs react-native redux redux-saga


【解决方案1】:

您应该在 componentDidMount 中调度操作。在安装组件之前调用构造函数,这就是您看到错误的原因。

这是一个反应生命周期的图表。你应该只在“提交”阶段调用改变状态的方法。

【讨论】:

  • 感谢您提供有用的信息。但是我不想每次安装组件时都调用服务器?我能做些什么呢?
  • 我尝试在 componentDidMount 中调度操作,但是一旦获取成功,上述警告仍然存在。我想是其他原因导致了这个问题。我猜它必须与我正在使用的平面列表做一些事情。
  • 仅供参考:请注意,其中一些生命周期方法仅对 React 16.3.0+ 有效。
  • 不建议从构造函数中引起任何副作用,调用构造函数肯定是。上面绿色的生命周期方法是唯一被认为是“安全”影响状态/道具的地方,因为异步渲染将成为 React w/ Fiber 重写的一部分。您的顶级组件不应该定期重新安装,这样就不会成为问题。您还可以在调度操作之前检查数据。
  • 如果你硬编码反应状态下的数据,你还看到问题吗?
【解决方案2】:

这个错误是在黄色框里说的时候触发的。您尝试更新已卸载的组件的某个地方。 我通过使用临时变量componentIsMounted: bool 和包装setState 方法处理了这个问题:

class SomeClass extends Component {
  constructor(props) {
    this._isComponentMounted = false;
  }

  componentDidMount() {
    this._isComponentMounted = true;
  }

  componentWillUnmount() {
    this._isComponentMounted = false;
  }

  setState(...args) {
    if (!this._isComponentMounted) {
      return;
    }

    super.setState(...args);
  }
}

另外,您应该记住,您不应该在组件挂载之前调用状态更新(这不是替代方式 - 只是添加)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多