这也有另一个解决方案,使用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})
正如您可能在我们的 new 中注意到的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
}
typescript支持。感谢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