gpt4 book ai didi

javascript - Redux + Hooks useDispatch() in useEffect calling action 两次

转载 作者:行者123 更新时间:2023-12-05 03:52:48 26 4
gpt4 key购买 nike

我是 redux 和 hooks 的初学者。我正在处理表单并尝试通过 useDispatch Hook 调用操作,但它调用了我的操作两次。

我指的是 this文章。

例子如下:

useProfileForm.js

import { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchProfile } from '../../../redux/profile/profile.actions';

const useProfileForm = (callback) => {

const profileData = useSelector(state =>
state.profile.items
);

let data;
if (profileData.profile) {
data = profileData.profile;
}

const [values, setValues] = useState(data);

const dispatch = useDispatch();

useEffect(() => {
dispatch(fetchProfile());
}, [dispatch]);

const handleSubmit = (event) => {
if (event) {
event.preventDefault();
}
callback();
};

const handleChange = (event) => {
event.persist();
setValues(values => ({ ...values, [event.target.name]: event.target.value }));
};

return {
handleChange,
handleSubmit,
values,
}
};

export default useProfileForm;

Action

export const FETCH_PROFILE_BEGIN = "FETCH_PROFILE_BEGIN";
export const FETCH_PROFILE_SUCCESS = "FETCH_PROFILE_SUCCESS";
export const FETCH_PROFILE_FAILURE = "FETCH_PROFILE_FAILURE";
export const ADD_PROFILE_DETAILS = "ADD_PROFILE_DETAILS";

function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}

function getProfile() {
return fetch("url")
.then(handleErrors)
.then(res => res.json());
}

export function fetchProfile() {
return dispatch => {
dispatch(fetchProfileBegin());
return getProfile().then(json => {
dispatch(fetchProfileSuccess(json));
return json;
}).catch(error =>
dispatch(fetchProfileFailure(error))
);
};
}

export const fetchProfileBegin = () => ({
type: FETCH_PROFILE_BEGIN
});

export const fetchProfileSuccess = profile => {
return {
type: FETCH_PROFILE_SUCCESS,
payload: { profile }
}
};

export const fetchProfileFailure = error => ({
type: FETCH_PROFILE_FAILURE,
payload: { error }
});

export const addProfileDetails = details => {
return {
type: ADD_PROFILE_DETAILS,
payload: details
}
};

reducer :

    import { ADD_PROFILE_DETAILS, FETCH_PROFILE_BEGIN, FETCH_PROFILE_FAILURE, FETCH_PROFILE_SUCCESS } from './profile.actions';

const INITIAL_STATE = {
items: [],
loading: false,
error: null
};

const profileReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case ADD_PROFILE_DETAILS:
return {
...state,
addProfileDetails: action.payload
}
case FETCH_PROFILE_BEGIN:
return {
...state,
loading: true,
error: null
};

case FETCH_PROFILE_SUCCESS:
return {
...state,
loading: false,
items: action.payload.profile
};

case FETCH_PROFILE_FAILURE:
return {
...state,
loading: false,
error: action.payload.error,
items: []
};
default:
return state;
}
}

export default profileReducer;


**Component:**

import React from 'react';
import { connect } from 'react-redux';
import useProfileForm from './useProfileForm';
import { addProfileDetails } from '../../../redux/profile/profile.actions';

const EducationalDetails = () => {

const { values, handleChange, handleSubmit } = useProfileForm(submitForm);

console.log("values", values);


function submitForm() {
addProfileDetails(values);
}

if (values) {
if (values.error) {
return <div>Error! {values.error.message}</div>;
}

if (values.loading) {
return <div>Loading...</div>;
}
}

return (
<Card>
...some big html
</Card>
)
}

const mapDispatchToProps = dispatch => ({
addProfileDetails: details => dispatch(details)
});

export default connect(null, mapDispatchToProps)(EducationalDetails);

此外,当我将数据从 const [values, setValues] = useState(data); useState 传递给 values 时,理想情况下我应该在组件中接收它,但我没有得到它显示未定义。

const { values, handleChange, handleSubmit } = useProfileForm(submitForm);

值未定义

enter image description here

enter image description here

最佳答案

两次分派(dispatch)操作可能是因为您在 React 层次结构中使用了 React.StrictMode

根据 react 文档,为了 detect unexpected sideEffects , react 两次调用某个函数如

Functions passed to useState, useMemo, or useReducer

现在由于 react-redux 是在 react API 之上实现的,所以操作实际上被调用了两次

另外,当我从 const [values, setValues] = useState(data); 传递数据时useState 到值然后理想情况下我应该在组件中收到它,但我没有收到,因为它显示未定义。

要回答这个问题,你必须知道 values 不是来自 reducer 的 dispatch action 的响应结果,而是在调用 handleChange 时更新的状态,因此应该保持不受 action 的影响

我想你的意思是从 useProfileForm 中公开 redux 数据,但忘了做

const useProfileForm = (callback) => {

const profileData = useSelector(state =>
state.profile.items
);

let data;
if (profileData.profile) {
data = profileData.profile;
}

const [values, setValues] = useState(data);

const dispatch = useDispatch();

useEffect(() => {
dispatch(fetchProfile());
}, [dispatch]);

const handleSubmit = (event) => {
if (event) {
event.preventDefault();
}
callback();
};

const handleChange = (event) => {
event.persist();
setValues(values => ({ ...values, [event.target.name]: event.target.value }));
};

return {
handleChange,
handleSubmit,
values,
data // This is the data coming from redux store on FetchProfile and needs to logged
}
};

export default useProfileForm;

您可以像这样使用组件中的数据

const { values, handleChange, handleSubmit, data } = useProfileForm(submitForm);

关于javascript - Redux + Hooks useDispatch() in useEffect calling action 两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62025911/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com