React and Redux

React and Redux

Dec 12, 2022

React and Redux are often mentioned together, and with good reason. The developer who created Redux was a React developer who wanted to make it easier to share data across different components.

Getting Started with React Redux

class DisplayMessages extends React.Component {

  constructor(props) {

    super(props)

    this.state = {

      input:"",

      massages: []

    }

  }

  render() {

    return <div />

  }

};

Manage State Locally First

class DisplayMessages extends React.Component {

  constructor(props) {

    super(props);

    this.state = {

      input: '',

      messages: []

    }

  }

  handleChange(event){

    this.setState({

      input: event.target.value,

      messages: this.state.messages

    })

  }


  submitMessage(){    this.setState({      input: "",      messages: [...this.state.messages, this.state.input]    })  }




  render() {    return (      <div>        <h2>Type in a new Message:</h2>        {  }<input onChange={this.handleChange.bind(this)} value={this.state.input}/>        <button onClick={this.submitMessage.bind(this)}>Submit</button>        <ul>          {this.state.messages.map((x, i)=>{            return <li key={i}>{x}</li>          })}        </ul>


        {  }      </div>    );  }};

Extract State Logic to Redux

const addMessage = (message) => {

  return {

    type: ADD,

    message

  }

}


const messageReducer = (state = [], action) => {  switch(action.type) {    case ADD:    return [...state, action.message]    default:    return state  }}
const store = Redux.createStore(messageReducer)

Use Provider to Connect Redux to React

// Redux:

const ADD = 'ADD';


const addMessage = (message) => {  return {    type: ADD,    message  }};
const messageReducer = (state = [], action) => {  switch (action.type) {    case ADD:      return [        ...state,        action.message      ];    default:      return state;  }};


const store = Redux.createStore(messageReducer);
// React:
class DisplayMessages extends React.Component {  constructor(props) {    super(props);    this.state = {      input: '',      messages: []    }    this.handleChange = this.handleChange.bind(this);    this.submitMessage = this.submitMessage.bind(this);  }  handleChange(event) {    this.setState({      input: event.target.value    });  }  submitMessage() {      this.setState((state) => {      const currentMessage = state.input;      return {        input: '',        messages: state.messages.concat(currentMessage)      };    });  }  render() {    return (      <div>        <h2>Type in a new Message:</h2>        <input          value={this.state.input}          onChange={this.handleChange}/><br/>        <button onClick={this.submitMessage}>Submit</button>        <ul>          {this.state.messages.map( (message, idx) => {              return (                 <li key={idx}>{message}</li>              )            })          }        </ul>      </div>    );  }};
const Provider = ReactRedux.Provider;
class AppWrapper extends React.Component {  render () {  return (
  <Provider store={store}><DisplayMessages/>
  </Provider>  )  }};

Map State to Props

const state = [];


const mapStateToProps = (state) => {  return {    messages: state  }}

Map Dispatch to Props

const addMessage = (message) => {

  return {

    type: 'ADD',

    message: message

  }

};


const mapDispatchToProps = (dispatch) => {  return {    submitNewMessage: (message) => {      return dispatch(addMessage(message))    }  }}

Connect Redux to React

const addMessage = (message) => {

  return {

    type: 'ADD',

    message: message

  }

};


const mapStateToProps = (state) => {  return {    messages: state  }};
const mapDispatchToProps = (dispatch) => {  return {    submitNewMessage: (message) => {      dispatch(addMessage(message));    }  }};
class Presentational extends React.Component {  constructor(props) {    super(props);  }  render() {    return <h3>This is a Presentational Component</h3>  }};
const connect = ReactRedux.connect;
const ConnectedComponent = connect(mapStateToProps, mapDispatchToProps)(Presentational)

Connect Redux to the Messages App

// Redux:

const ADD = 'ADD';


const addMessage = (message) => {  return {    type: ADD,    message: message  }};
const messageReducer = (state = [], action) => {  switch (action.type) {    case ADD:      return [        ...state,        action.message      ];    default:      return state;  }};
const store = Redux.createStore(messageReducer);
// React:class Presentational extends React.Component {  constructor(props) {    super(props);    this.state = {      input: '',      messages: []    }    this.handleChange = this.handleChange.bind(this);    this.submitMessage = this.submitMessage.bind(this);  }  handleChange(event) {    this.setState({      input: event.target.value    });  }  submitMessage() {    this.setState((state) => {      const currentMessage = state.input;      return {        input: '',        messages: state.messages.concat(currentMessage)      };    });  }  render() {    return (      <div>        <h2>Type in a new Message:</h2>        <input          value={this.state.input}          onChange={this.handleChange}/><br/>        <button onClick={this.submitMessage}>Submit</button>        <ul>          {this.state.messages.map( (message, idx) => {              return (                 <li key={idx}>{message}</li>              )            })          }        </ul>      </div>    );  }};
// React-Redux:const mapStateToProps = (state) => {  return { messages: state }};
const mapDispatchToProps = (dispatch) => {  return {    submitNewMessage: (newMessage) => {       dispatch(addMessage(newMessage))    }  }};
const Provider = ReactRedux.Provider;const connect = ReactRedux.connect;
const Container = connect(mapStateToProps, mapDispatchToProps)(Presentational)

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

Extract Local State into Redux

// Redux:

const ADD = 'ADD';


const addMessage = (message) => {  return {    type: ADD,    message: message  }};
const messageReducer = (state = [], action) => {  switch (action.type) {    case ADD:      return [        ...state,        action.message      ];    default:      return state;  }};
const store = Redux.createStore(messageReducer);
// React:const Provider = ReactRedux.Provider;const connect = ReactRedux.connect;

class Presentational extends React.Component {  constructor(props) {    super(props);    this.state = {      input: '',
    }    this.handleChange = this.handleChange.bind(this);    this.submitMessage = this.submitMessage.bind(this);  }  handleChange(event) {    this.setState({      input: event.target.value    });  }  submitMessage() {    this.props.submitNewMessage(this.state.input)    this.setState((state) => ({      input: ''    }));  }  render() {    return (      <div>        <h2>Type in a new Message:</h2>        <input          value={this.state.input}          onChange={this.handleChange}/><br/>        <button onClick={this.submitMessage}>Submit</button>        <ul>          {this.props.messages.map( (message, idx) => {              return (                 <li key={idx}>{message}</li>              )            })          }        </ul>      </div>    );  }};

const mapStateToProps = (state) => {  return {messages: state}};
const mapDispatchToProps = (dispatch) => {  return {    submitNewMessage: (message) => {      dispatch(addMessage(message))    }  }};
const Container = connect(mapStateToProps, mapDispatchToProps)(Presentational);
class AppWrapper extends React.Component {  render() {    return (      <Provider store={store}>        <Container/>      </Provider>    );  }};

Moving Forward From Here

Enjoy this post?

Buy SEMIH a coffee

More from SEMIH