这也有另一个解决方案使用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