📅  最后修改于: 2023-12-03 14:44:08.691000             🧑  作者: Mango
在Redux中,我们经常需要将一个动作(action)与一个组件的属性连接起来。这时,我们可以使用 mapDispatchToProps
函数。
mapDispatchToProps
函数接收一个 dispatch
函数作为参数,并返回一个对象,该对象的属性名表示该组件需要的方法,属性值是一个函数,该函数返回一个对象,表示该方法对应的动作。
例如,我们有以下 action:
const incrementCounter = (amount) => {
return {
type: 'INCREMENT_COUNTER',
amount
};
};
我们需要将这个动作与一个名为 Counter
的组件连接起来,这时我们可以先编写一个 mapDispatchToProps
函数:
const mapDispatchToProps = (dispatch) => {
return {
increment: (amount) => dispatch(incrementCounter(amount))
};
};
这个函数接收 dispatch
作为参数,然后返回一个对象。该对象包含一个 increment
方法,该方法接收 amount
作为参数,内部调用了 incrementCounter
并将其结果传递给 dispatch
函数。
接下来我们用 connect
函数将 Counter
组件与 mapDispatchToProps
函数连接起来:
import { connect } from 'react-redux';
import Counter from './Counter';
const mapStateToProps = (state) => {
return {
count: state.count
};
};
const mapDispatchToProps = (dispatch) => {
return {
increment: (amount) => dispatch(incrementCounter(amount))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
这里用到了 connect
函数,该函数接收两个参数,分别为 mapStateToProps
和 mapDispatchToProps
函数。它返回一个函数,该函数接收一个组件作为参数,并返回一个新的组件,两个函数的返回结果都会作为新组件的属性传递进去。
这样,我们就成功将 incrementCounter
动作与 Counter
组件连接了起来。在 Counter
组件中可以通过 this.props.increment()
来调用该方法,从而触发 incrementCounter
动作。
有时候,我们可能需要更复杂的 mapDispatchToProps
函数,例如使用异步操作或使用多个动作。
我们可以将异步操作封装成一个函数并返回一个动作,然后在 mapDispatchToProps
中进行调用。
例如,我们有以下异步操作:
const fetchPosts = () => {
return (dispatch) => {
dispatch({ type: 'FETCH_POSTS_REQUEST' });
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(posts => dispatch({ type: 'FETCH_POSTS_SUCCESS', posts }))
.catch(err => dispatch({ type: 'FETCH_POSTS_FAILURE', error: err }));
};
};
这个函数会发送一个 AJAX 请求,然后根据请求结果返回不同的动作。我们将它封装成一个函数返回一个动作对象。
然后我们可以在 mapDispatchToProps
中将这个函数绑定到一个组件的属性上:
const mapDispatchToProps = (dispatch) => {
return {
fetchPosts: () => dispatch(fetchPosts())
};
};
这样,在组件中就可以通过 this.props.fetchPosts()
来触发异步操作,并在请求完成后触发相应的动作了。
在某些情况下,我们可能需要触发多个动作。我们可以绑定一个对象作为属性,该对象将其属性与要触发的动作进行映射。
例如,我们有以下两个动作:
const selectCountry = (countryId) => {
return {
type: 'SELECT_COUNTRY',
countryId
};
};
const fetchCities = (countryId) => {
return (dispatch) => {
dispatch({ type: 'FETCH_CITIES_REQUEST' });
fetch(`/api/cities?country=${countryId}`)
.then(res => res.json())
.then(cities => dispatch({ type: 'FETCH_CITIES_SUCCESS', cities }))
.catch(err => dispatch({ type: 'FETCH_CITIES_FAILURE', error: err }));
};
};
我们可以将这两个动作绑定到一个组件的属性上:
const mapDispatchToProps = (dispatch) => {
return {
actions: {
selectCountry: (countryId) => dispatch(selectCountry(countryId)),
fetchCities: (countryId) => dispatch(fetchCities(countryId))
}
};
};
然后在组件中可以这样使用:
this.props.actions.selectCountry(countryId);
this.props.actions.fetchCities(countryId);
这样,我们就可以触发多个动作了。
mapDispatchToProps
是一个用于将动作与组件进行连接的函数。我们可以在该函数中定义组件需要的方法,并返回一个对象,该对象的属性名表示该方法,属性值表示与之对应的动作或异步操作。
在编写该函数时,我们需要注意以下几个问题:
dispatch
作为参数,用于触发动作使用 mapDispatchToProps
可以使代码更清晰,角色更明确,是一个非常重要的问题。