当反应16.8引入反应钩子时,访问和设置状态已经改变。以前你可以使用{this.state}
访问整个状态对象,现在因为你直接访问你的状态,如{count}
vs {this.state.count}
,我找不到访问整个状态对象的方法。是否有可能以新的编写反应组件的方式检索整个状态对象?
更清楚;我有一个React组件,它将组件状态作为props并在UI中显示它以进行调试。我知道我可以使用react插件,但我发现在我编码时在UI中显示状态更有效。
const {
useState
} = React;
function App() {
class MyComponent extends React.Component {
constructor(props: RectangularSelectProps) {
super(props);
this.state = {
expanded: false,
otherStuff: {
string: 'bla bla'
}
};
}
render() {
return ( < React.Fragment >
Component:
<div> *** Component Code ** * </div>
Debug:
<div style = {{margin: '1rem 0'}} >
<h3 style = {{fontFamily: 'monospace'}}/> <pre style = {
{
background: '#f6f8fa',
fontSize: '.65rem',
padding: '.5rem',
}
} > {
JSON.stringify({ ...this.state
}, null, 2)
} </pre> </div> </React.Fragment>)
}
}
return ( < div > < MyComponent / > < /div>);
}
ReactDOM.render( < App / > , document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
与将类状态保持为对象的类组件中的状态不同,使用useState
钩子不限制状态类型。它可以把国家作为string, boolean, number, object or array
。唯一需要注意的是,setState会将更新后的状态对象与之前的状态合并,而hooks setter则不会这样做。您还可以在组件中具有多个具有多个不同状态类型的useState声明
使用useState
钩子的例子是
const [count, setCount] = useState(0);
const [name, setName] = useState('Mr A');
const [isOpen, setIsOpen] = useState(false);
const [user, setUser] = useState({ name: 'Mr B', email: '[email protected]'});
const [items, setItems] = useState(['Foo', 'Bar']);
useState
的每次使用都有自己的参考,并返回州和它的二传手。
useState
的setter以新的state值传递。它还可以采用一个回调函数,该函数传递先前的状态值
例
setUser({name: 'Mr C', email: '[email protected]'});
要么
setUser(prevState => ({...prevState, email:'[email protected]'}))
DEMO
const { useState } = React;
function App() {
const [state, setState] = useState({ name: "A", email: "[email protected]" });
const [count, setCount] = useState(0);
return (
<div>
<div onClick={() => setState(prevState => ({ ...prevState, name: 'B' }))}>
{state.name}
</div>
<div>{count}</div>
<button onClick={() => setCount(prevCount => prevCount + 1)}>
Click To increment count
</button>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
附:在大多数情况下,useState
将为您服务。但是,如果你的州变得复杂并且需要复杂的突变,那么useReducer
是最好的前进方式。你可以看看文档here
如果将它分成几个useState
钩子,则无法访问整个状态,但是你仍然可以使用一个useState
钩子和一个用作状态的对象将它们全部放在一个地方。
但是,使用钩子更新状态将替换整个现有状态,因此使用此方法需要将其与现有状态对象合并。
例
const { useState } = React;
function App() {
const [state, setState] = useState({ foo: "foo", bar: "bar" });
return (
<div>
<button onClick={() => setState({ ...state, foo: Math.random() })}>
{state.foo}
</button>
<button onClick={() => setState({ ...state, bar: Math.random() })}>
{state.bar}
</button>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
如果你真的需要一些复杂的结构,你可以使用useReducer来获得类似于this.state
的东西。