这也有另一个解决方案使用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})
Awesome,哈? !
所以让我们把所有的片段放在一起:
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要求一种方法来访问setState中的prevState,所以这里有一种方法来实现这个目标:
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