简体   繁体   中英

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. 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.

// 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. Instead it renders nothing and throws:

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

Well the problem is in your App component. You missed the return there, so the render method by default returns undefined and that is what cause of the error you are seeing. Another fix will be to remove the dispatch that will give you runttime error once you fix the missing return in the App component.

Corrected App component is:

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

And dispatch(this.props.submitUpdate(event)); should be this.props.submitUpdate(event); inside the Presentational component handleChange method.

Full working code:

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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