这还有另一个解决方案使用!首先,我们定义我们的新.useReducer
setState
const [state, setState] = useReducer(
(state, newState) => ({...state, ...newState}),
{loading: true, data: null, something: ''}
)
在那之后,我们可以简单地使用它,就像旧的类一样,只是没有!this.setState
this
setState({loading: false, data: test.data.results})
正如您可能在我们的新项目中注意到的那样(就像我们之前一样),我们不需要一起更新所有状态!例如,我可以像这样改变我们的一个状态(它不会改变其他状态!setState
this.setState
setState({loading: false})
真棒,哈?!
因此,让我们将所有部分放在一起:
import {useReducer} from 'react'
const getData = url => {
const [state, setState] = useReducer(
(state, newState) => ({...state, ...newState}),
{loading: true, data: null}
)
useEffect(async () => {
const test = await api.get('/people')
if(test.ok){
setState({loading: false, data: test.data.results})
}
}, [])
return state
}
类型脚本支持。感谢P. Galbraith回答了这个解决方案,那些使用typescript的人可以使用这个:
useReducer<Reducer<MyState, Partial<MyState>>>(...)
其中 是状态对象的类型。MyState
例如,在我们的例子中,它将是这样的:
interface MyState {
loading: boolean;
data: any;
something: string;
}
const [state, setState] = useReducer<Reducer<MyState, Partial<MyState>>>(
(state, newState) => ({...state, ...newState}),
{loading: true, data: null, something: ''}
)
以前的状态支持。在评论中,user2420374要求一种方法来访问我们的内部,所以这里有一种方法可以实现这一目标:prevState
setState
const [state, setState] = useReducer(
(state, newState) => {
newWithPrevState = isFunction(newState) ? newState(state) : newState
return (
{...state, ...newWithPrevState}
)
},
initialState
)
// And then use it like this...
setState(prevState => {...})
isFunction
检查传递的参数是函数(这意味着您正在尝试访问 prevState)还是普通对象。你可以在这里找到 Alex Grande 的 isFunction 的这个实现。
注意。对于那些想经常使用这个答案的人,我决定把它变成一个图书馆。你可以在这里找到它:
Github: https://github.com/thevahidal/react-use-setstate
NPM: https://www.npmjs.com/package/react-use-setstate