В этом случае проблема заключается в том, что вызванный handleForm все еще имеет доступ только к состоянию formValues во время его вызова, а не к новому состоянию. Итак, самый простой способ справиться с этим - просто обновить formValues, setFormValues, а затем setTweetList на основе локальной копии обновленных formValues.
const handleForm = () => {
const {userName,tweetText} = formValues;
if(!userName || !tweetText) {
console.log('your tweet is empty');
} else {
const updatedFormValues = {...formValues,date:getCurrentDate()};
setformValues(updatedFormValues)
setTweetList(prevTweets => ([...prevTweets, updatedFormValues]));
toggleHidden(!isOpen)
}
}
Поскольку здесь есть проблемы с параллелизмом: то есть вы можете ' Гарантировать обновление состояния formValues и tweetList с последними данными. Другой вариант - использовать useReducer вместо двух отдельных переменных состояния, потому что они являются связанными свойствами, и вы сможете легко обновлять их на основе друг друга.
В качестве примера более сложных обновлений с помощью редукторов, Я добавил действие 'FINALIZE_TWEET', которое будет выполнять обе части действия одновременно.
const Component = () => {
const [{ formValues, tweetList }, dispatch] = useReducer(
reducer,
undefined,
getInitState
);
const handleInput = (inputName, inputValue) => {
dispatch({ type: 'SET_FORM_VALUE', payload: { inputName, inputValue } });
};
const handleForm = () => {
const { userName, tweetText } = formValues;
if (!userName || !tweetText) {
console.log('your tweet is empty');
} else {
dispatch({ type: 'SET_FORM_DATE' });
dispatch({ type: 'PUSH_TO_LIST' });
// OR
// dispatch({type: 'FINALIZE_TWEET'})
toggleHidden(!isOpen);
}
};
console.log(formValues); //but you can see changes outside the function
useEffect(() => {
localStorage.setItem('tweetList', JSON.stringify(tweetList));
}, [tweetList]);
return <div></div>;
};
const getlocalValue = () => {
const localValue = JSON.parse(localStorage.getItem('tweetList'));
if (localValue !== null) {
return localValue;
} else {
return [];
}
};
function getInitState() {
const initialState = {
formValues: {
userName: '',
tweetText: '',
date: '',
},
tweetList: getlocalValue(),
};
}
function reducer(state, action) {
switch (action.type) {
case 'SET_FORM_VALUE':
return {
...state,
formValues: {
...state.formValues,
[action.payload.inputName]: action.payload.inputValue,
},
};
case 'SET_FORM_DATE':
return {
...state,
formValues: {
...state.formValues,
date: getCurrentDate(),
},
};
case 'PUSH_TO_LIST':
return {
...state,
tweetList: [...state.tweetList, state.formValues],
};
case 'FINALIZE_TWEET': {
const newTweet = {
...state.formValues,
date: getCurrentDate(),
};
return {
...state,
formValues: newTweet,
tweetList: [...state.tweetList, newTweet],
};
}
default:
return state;
}
}