【问题标题】:How to fix "Invariant violation" error in React如何修复 React 中的“不变违反”错误
【发布时间】:2019-07-10 14:51:17
【问题描述】:

我正在尝试使用 React-Redux 制作一个简单的网站,以练习使用 React 和 Redux 并将它们连接起来。整个 HTML 只是一个 id="container" 的 div,用于从代码末尾的 ReactDOM.render 接收最终组件。

// Redux
const defaultState = {
  input: ""
}

const updateView = (event) => {
  return {
    type: "UPDATE",
    input: event.target.value
  }
}

const reducer = (state = defaultState, action) => {
  switch(action.type) {
    case "UPDATE":
      return {
        input: action.input
      }
    default:
      return state
  }
}

const store = Redux.createStore(reducer);

// React Redux
const connect = ReactRedux.connect;
const Provider = ReactRedux.Provider;

// React
class Presentational extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    dispatch(this.props.submitUpdate(event));
  }
  render() {
    return (
      <div>
        <textarea cols="40" rows="10" value={this.props.input} onChange={this.handleChange}/>
        <div id="preview"></div>
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    input: state.input
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    submitUpdate: function(event) {
      dispatch(updateView(event));
    }
  }
}

const Container = connect(mapStateToProps, mapDispatchToProps)(Presentational);

class App extends React.Component {
  constructor(props) {
    super(props)
  }
  render() {
    <Provider store={store}>
      <Container/>
    </Provider>
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

我最终希望它成为一个 Markdown 预览器,但现在我希望它呈现一个我可以输入的文本区域,并且在幕后它应该更改 state 的输入属性,以便我以后可以访问它。相反,它什么也不渲染并抛出:

[object Error] {
    framesToPop: 1,
    name: "Invariant Violation"
}

【问题讨论】:

  • 看起来dispatch(this.props.submitUpdate(event)); 应该是this.props.submitUpdate(event);
  • 这也可能是真的,但改变并不能解决问题

标签: javascript reactjs redux react-redux


【解决方案1】:

问题出在您的App 组件中。您在那里错过了return,因此默认情况下渲染方法返回undefined,这就是您看到错误的原因。另一个修复方法是删除dispatch,一旦您修复了App 组件中缺少的返回,这会给您带来runttime 错误。

更正App 组件为:

class App extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <Provider store={store}>
        <Container />
      </Provider>
    );
  }
}

并且dispatch(this.props.submitUpdate(event)); 应该是this.props.submitUpdate(event);Presentational 组件handleChange 方法中。

完整的工作代码:

index.js

// Redux
const defaultState = {
  input: ""
};

const updateView = event => {
  return {
    type: "UPDATE",
    input: event.target.value
  };
};

const reducer = (state = defaultState, action) => {
  switch (action.type) {
    case "UPDATE":
      return {
        input: action.input
      };
    default:
      return state;
  }
};

const store = Redux.createStore(reducer);

// React Redux
const connect = ReactRedux.connect;
const Provider = ReactRedux.Provider;

// React
class Presentational extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.props.submitUpdate(event);
  }
  render() {
    return (
      <div>
        <textarea
          cols="40"
          rows="10"
          value={this.props.input}
          onChange={this.handleChange}
        />
        <div id="preview" />
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    input: state.input
  };
};

const mapDispatchToProps = dispatch => {
  return {
    submitUpdate: function(event) {
      dispatch(updateView(event));
    }
  };
};

const Container = connect(
  mapStateToProps,
  mapDispatchToProps
)(Presentational);

class App extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <Provider store={store}>
        <Container />
      </Provider>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <script
      crossorigin
      src="https://unpkg.com/react@16/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
    ></script>
    <script src="https://unpkg.com/react-redux@6.0.0/dist/react-redux.js"></script>

    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script src="https://unpkg.com/redux@4.0.1/dist/redux.js"></script>
    <title>Document</title>
  </head>
  <body>
    <div id="container"></div>
    <script type="text/babel" src="index.js"></script>
  </body>
</html>

【讨论】:

  • 在一个层面上,我不敢相信我是如此愚蠢。在另一个层面上,我知道肯定会发生愚蠢的错别字。感谢您为我找到它!
猜你喜欢
  • 2019-11-22
  • 2020-01-11
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 2018-12-19
  • 2017-02-25
  • 2020-03-07
  • 2020-01-17
相关资源
最近更新 更多