31
loading...
This website collects cookies to deliver better user experience
Provider
and connect
.Provider
. It's a wrapper component from React Redux that wraps your React app. Which then allows us to access the Redux store
and dispatch
functions throughout our component tree. Provider
takes two props, the Redux store and the child components of our app.// 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 the Provider below this line
render() {
return (
<Provider store={store}>
<DisplayMessages/>
</Provider>
)
}
};
As you can see, we rendered the Provider
from ReactRedux
and passed the Redux store as a prop. Then we rendered the DisplayMessages
component as a child. Once we finished, we can see our React component rendered to the page.
Obviously there's a lot more to learn about this but I'm just basics.
Provider
component allows you to provide state
and dispatch
to your React components, but you must specify exactly what state and actions you want.mapStateToProps()
and mapDispatchToProps()
.mapStateToProps
. For this function it will take state
as an argument, then return an object which maps that state to specific property names. Then create a property messages
in the object that's being returned and set it to state
.
const state = [];
function mapStateToProps(state) {
return {
messages: state
}
}
props
. FreeCodeCamp provides us with the store.subscribe
method to implement mapStateToProps()
behind the scenes.mapDispatchToProps()
function is used to provide specific action creators to your React components so they can dispatch actions against the Redux store. It also returns an object that maps dispatch actions to property names, which become component props
. With that, each property returns a function that calls dispatch
with an action creator and any relevant action data.mapDispatchToProps()
as a parameter when you define the function, just like you passed state
to mapStateToProps()
store.dispatch
addMessage()
action creator that takes a message
as an action payload. The object returned from mapDispatchToProps()
for this action creator would look like this.
const addMessage = (message) => {
return {
type: 'ADD',
message: message
}
};
function mapDispatchToProps(dispatch) {
return {
submitNewMessage: (message) => {
dispatch(addMessage(message))
}
}
}
submitNewMessage
set to the dispatch function, which takes a parameter for the new message to add when it dispatches addMessage()
.mapStateToProps
and the mapDispatchToProps
functions, you can use them to map state
and dispatch
to the props
of one of our React components. connect
method has two optional arguments, mapStateToProps()
and mapDispatchToProps()
. They are optional because you may have a component that only needs access to state but doesn't need to dispatch any actions, or vice versa.connect(mapStateToProps, mapDispatchToProps)(MyComponent)
Presentational
to Redux with the connect method from the ReactRedux
global object, and call it on the Presentational
component. Assigning the result to a new const
called ConnectedComponent
that represents the connected component.
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
we can now apply what we've learned to our React Component that handles messages.Container
that uses connect
to connect the Presentational
component to Redux. Then, in the AppWrapper
, render the React Redux Provider component. Pass Provider the Redux store as a prop and render Container
as a child. Once everything is setup, you will see the messages app rendered to the page.
const mapStateToProps = (state) => {
return { messages: state }
};
const mapDispatchToProps = (dispatch) => {
return {
submitNewMessage: (newMessage) => {
dispatch(addMessage(newMessage))
}
}
};
const Provider = ReactRedux.Provider;
const connect = ReactRedux.connect;
// Define the Container component here:
class AppWrapper extends React.Component {
constructor(props) {
super(props);
}
render() {
// Complete the return statement:
return (null);
}
};
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>
);
}
};
messages
property in the local state. These messages will be managed by Redux. submitMessage()
method so that it dispatches submitNewMessage()
from this.props
, and pass in the current message input from local state
as an argument. Because you removed messages from local state, remove the messages property from the call to this.setState()
here as well. Finally, modify the render()
method so that it maps over the messages received from props
rather than state
.
submitMessage() {
this.setState((state) => ({
input: '',
messages: state.messages.concat(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.state.messages.map( (message, idx) => {
return (
<li key={idx}>{message}</li>
)
})
}
</ul>
</div>
);
}
};
submitMessage() {
this.props.submitNewMessage(this.state.input)
this.setState({
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>
);
}
};