将参数传递给 mapDispatchToProps()

IT技术 reactjs redux react-redux
2021-05-06 15:12:11

我不能撒谎,我对 react-redux 有点困惑。我认为很多操作都需要参数(例如从商店中删除项目),但即使我仍在阅读有关如何以这种方式从组件分派以传递参数的信息,现在大约 2 小时,我也没有得到任何答案。我尝试过this.props.dispatchmapDispatchToProps,我总是收到this.props... is not a function消息。这是我想要做的:

  const getTheArray = (array) => {
    return {
      type: 'GET_ARRAY',
      array
    }
  }
    
    class Example extends......
    
    componentDidUpdate(){
    //i have a button, and when it clicked, turns the status: 'deleted'
        if (this.state.status === 'deleted'){
            fetch('http://localhost:3001/deleteitem', {
                method: 'post',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({
                    id: this.props.id
                })
            })
            .then(res => res.json())
            .then(data => this.props.deleteFromArray(data))
            .catch(err => console.log(err)) 
        }
    }




function mapStateToProps(state) {
    return {
        array: state.array
    };
}
function mapDispatchToProps(dispatch) {
    return({
        deleteFromArray: (array) => {dispatch(getTheArray(array))}
    })
}
  
export default connect(mapStateToProps, mapDispatchToProps)(Example);

这不是我需要用动作调度的唯一地方,动作对象的属性取决于传递给函数的另一个属性,所以我真的很想做,将属性传递给动作并调度它的最佳方法是什么在react组件中。

4个回答
import { bindActionCreators } from "redux"

function mapDispatchToProps(dispatch) {
    return(bindActionCreators({
        deleteFromArray: (array) => {getTheArray(array)}
    }, dispatch))
}

在你的哑组件中,只需调用例如 this.props.deleteFromArray([1,2,3,4])

这应该可以解决问题。您不受派遣的约束

使用 react-redux

你需要先导入动作

import { storeProfiles } from 'actions/profiles';

定义props

 const {
     storeProfiles
  } = props;

使用 userEffect 获取数据

useEffect(() => {
    fetchProfiles().then(storeProfiles);
  }, [ fetchProfiles, storeProfiles ]);

映射到props

const mapDispatchToProps = dispatch => ({
 
  storeProfiles: x => dispatch(storeProfiles(x))
});
export default connect(mapStateToProps, mapDispatchToProps)(Component);

阅读官方文档

使用es6: const mapDispatchToProps = (dispatch) => ({ addToCart: (params) => dispatch(actions.addToCart(params)), });

实际上,在我看来,您不必将参数传递给这样的操作。我正在将 React Hooks 与 TypeScript、Redux 和 thunk 一起使用。我使用动作创建者删除帖子的方式如下所示:

PostDetails.tsx 组件:

import {deletePost, getPost, LanguageActionTypeEnum} from "../../../../app/store/aspian-core/actions";

interface IPostDetailsProps {
    getPost: Function;

    // action for deleting a post
    deletePost: Function;

    loadingInitial: boolean;
    submitting: boolean;
    post: IPost | undefined;
    lang: LanguageActionTypeEnum;
}

const PostDetails: FC<PostDetailsProps> = ({
                                               match, getPost,
                                               lang, loadingInitial,
                                               submitting, deletePost, post
                                           }) => {



}


// To delete a post
    const onDeleteBtnClick = async (id: string) => {
        try {

            /// using deletePost action and passing id to it
            await deletePost(id);

            message.success(t('messages.post-deleting-success'));
        } catch (error) {
            message.error(t('messages.post-deleting-error'));
        }
    };

return (

   // omitted for brevity

   <Popconfirm
                    key={uuidv4()}
                    title={t('popconfirm.title')}
                    
                    /// calling onDeleteBtnClick() here
                    onConfirm={() => onDeleteBtnClick(post!.id)}  

                    okText={t('popconfirm.ok-text')}
                    cancelText={t('popconfirm.cancel-text')}
                    placement={lang === LanguageActionTypeEnum.en ? 'left' : 'right'}
                    okButtonProps={{
                        danger: true,
                    }}
                >
                    <Button
                        loading={submitting}
                        size="small"
                        type="primary"
                        icon={<DeleteFilled/>}
                        danger
                    >
                        {t('buttons.delete')}
                    </Button>
                </Popconfirm>

     // omitted for brevity
  )

}

// Redux State To Map
const mapStateToProps = ({post, locale}: IStoreState): { post: IPost | undefined, submitting: boolean, loadingInitial: boolean, lang: LanguageActionTypeEnum } => {
    return {
        post: post.post,
        submitting: post.submitting,
        loadingInitial: post.loadingInitial,
        lang: locale.lang
    }
}

// Redux Dispatch To Map
const mapDispatchToProps = {
    getPost,

    // mapped deletePost action to props here
    // and I will be able to pass id to its argument later
    deletePost
}

export default connect(mapStateToProps, mapDispatchToProps)(PostDetails);

我的动作创建者看起来像这样:

postActions.ts:

export const deletePost = (id: string) => async (dispatch: Dispatch) => {
    try {
        dispatch(setPostSubmitting(true));
        await agent.Posts.delete([id]);

        dispatch<IDeletePostAction>({
            type: PostActionTypes.DELETE_SINGLE_POST,
            payload: {
                id,
                submitting: false
            }
        })
    } catch (error) {
        console.log(error);
        dispatch(setPostSubmitting(false));
        throw error;
    }
}

它工作正常。希望它可以帮助您解决您的情况。