javascript - 为什么我在 setState 上遇到不变违规 : Invariant Violation: Maximum update depth exceeded.?

标签 javascript reactjs ecmascript-6

我有这个组件:

// imports

export default class TabViewExample extends Component {
  state = {
    index: 0,
    routes: [
      { key: 'first', title: 'Drop-Off', selected: true },
      { key: 'second', title: 'Pick up', selected: false },
    ],
  };

  handleIndexChange = index => this.setState({ index });

  handleStateIndexChange = () => { // FUNCTION WITH THE ERROR
    const { index } = this.state;
    this.setState(({ routes }) => ({
      routes: routes.map((route, idx) => ({
        ...route,
        selected: idx === index,
      })),
    }));
  };

  renderTabBar = props => {
    const { routes } = this.state;
    this.handleStateIndexChange(); // HERE I GET THE ERROR
    return (
      <View style={tabViewStyles.tabBar}>
        {props.navigationState.routes.map((route, i) => {
          return (
            <>
              <TouchableOpacity
                key={route.key}
                style={[
                  tabViewStyles[`tabStyle_${i}`],
                ]}
                onPress={() => this.setState({ index: i })}
              >
                <Text>
                  {route.title}
                </Text>
                // THE FUNCTION ATTEMPTS TO SHOW AN ELEMENT WHEN
                // THE INDEX OF A ROUTE IS selected true
                {routes[i].selected && (
                  <View
                    style={{
                      flex: 1,
                    }}
                  >
                    <View
                      style={{
                        transform: [{ rotateZ: '45deg' }],
                      }}
                    />
                  </View>
                )}
              </TouchableOpacity>
            </>
          );
        })}
      </View>
    );
  };

  renderScene = SceneMap({
    first: this.props.FirstRoute,
    second: this.props.SecondRoute,
  });

  render() {
    return (
      <TabView
        navigationState={this.state}
        renderScene={this.renderScene}
        renderTabBar={this.renderTabBar}
        onIndexChange={this.handleIndexChange}
      />
    );
  }
}

完整错误:

Invariant Violation: Invariant Violation: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

这是给出错误的函数:

  handleStateIndexChange = () => { // FUNCTION WITH THE ERROR
    const { index } = this.state;
    this.setState(({ routes }) => ({
      routes: routes.map((route, idx) => ({
        ...route,
        selected: idx === index,
      })),
    }));
  };

我需要的只是将 selected 的状态设置为 true,这样我就可以切换组件的可见性。

最佳答案

如上面的评论所述,您不能直接在渲染函数内调用 setState

我认为没有任何理由将 selected 值保留在您的状态中,因为它仅取决于其中已有的另一个值,此信息是多余的。

您应该从 routes 中的所有对象中删除 selected 并更改您的 JSX 条件:

{routes[i].selected &&

至以下内容:

{i === this.state.index &&

产生相同的结果。

您现在可以从代码中删除handleStateIndexChange

关于javascript - 为什么我在 setState 上遇到不变违规 : Invariant Violation: Maximum update depth exceeded.?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54657365/

相关文章:

javascript - React.js - 如何使用来自子项的参数在父项中执行函数

javascript - 使用 React Router 以编程方式更改路由时出现问题

javascript - 一个令人困惑的 JavaScript ES6 字符串模板语法示例

javascript - 单独文档中的事件处理程序

javascript - 什么是 prototype.constructor 及其在原型(prototype)链中的作用 - Javascript

javascript - 回到像 Vue.js vuex 上的 Undo Redo 这样的状态

php - 将 friend 姓名的 php 字符串传递给 javascript 函数

javascript - React 动画在组件卸载时不起作用

javascript - ES6 从现有实例实例化派生类

javascript - 在 React Native 中裁剪图像