简体   繁体   English

如何在React中修复“不变违规”错误

[英]How to fix “Invariant violation” error in React

I'm trying to make a simple website using React-Redux to get practice using React and Redux and connecting them. 我正在尝试使用React-Redux创建一个简单的网站,以练习使用React和Redux并将它们连接起来。 The entire HTML is simply a div with id="container" to receive the final component from the ReactDOM.render at the end of the code. 整个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"));

I eventually want this to become a markdown previewer, but for now I expect it to render a textarea which I can type in, and behind the scenes it should change the input property of state so I can access that later. 我最终希望它成为markdown预览器,但是现在我希望它呈现一个可以键入的文本区域,并且在后台应更改state的input属性,以便以后可以访问它。 Instead it renders nothing and throws: 相反,它什么也不渲染并抛出:

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

Well the problem is in your App component. 问题出在您的App组件中。 You missed the return there, so the render method by default returns undefined and that is what cause of the error you are seeing. 您错过了return ,因此默认情况下render方法返回的是undefined ,这就是导致您看到错误的原因。 Another fix will be to remove the dispatch that will give you runttime error once you fix the missing return in the App component. 另一个解决方法是,一旦您修复了App组件中缺少的返回值,将删除将给您Runttime错误的dispatch

Corrected App component is: 更正后的App组件为:

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

And dispatch(this.props.submitUpdate(event)); dispatch(this.props.submitUpdate(event)); should be this.props.submitUpdate(event); 应该是this.props.submitUpdate(event); inside the Presentational component handleChange method. Presentational组件handleChange方法中。

Full working code: 完整的工作代码:

index.js 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 的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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM