React中的useState()是什么?

Hem*_*ari 51 javascript reactjs react-native react-hooks

我目前正在学习React中的钩子概念,并试图理解下面的例子.

import { useState } from 'react';

function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

上面的示例在处理程序函数参数本身上递增计数器.如果我想修改事件处理函数内的计数值怎么办?

考虑下面的例子

setCount = () => {
  //how can I modify count value here. Not sure if I can use setState to modify its value
  //also I want to modify other state values as well here. How can I do that
}

<button onClick={() => setCount()}>
  Click me
</button>
Run Code Online (Sandbox Code Playgroud)

Enm*_*ran 53

React钩子是一种新的方式(仍在开发中)来访问反应的核心功能,例如state无需使用类,在您的示例中,如果您想直接在处理函数中递增计数器而不直接在onClickprop中指定它,您可以这样做:

...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...

const setCount = () => {
    setCounter(count + 1);
    setMoreStuff(...);
    ...
};
Run Code Online (Sandbox Code Playgroud)

并点击:

<button onClick={setCount}>
    Click me
</button>
Run Code Online (Sandbox Code Playgroud)

我写了多个例子挂钩一个完整的文章(包括计数器)如本codepen,我利用了useState(0),count,setCounter,和自定义挂钩.文档还很好地解释了状态挂钩和其他挂钩是如何工作的,希望它有所帮助.

更新: 挂钩不再是提案,因为版本16.8现在可供使用,React的网站中有一个部分可以回答部分常见问题解答.

  • 很好的类比,只不过 JavaScript 在技术上没有元组数据类型 (7认同)

loe*_*onk 22

useState0.16.7版本中提供的内置react挂钩之一。

useState只能在功能组件内部使用。useState这是我们需要内部状态并且不需要实现更复杂的逻辑(例如生命周期方法)的方式。

const [state, setState] = useState(initialState);
Run Code Online (Sandbox Code Playgroud)

返回一个有状态值,以及一个更新它的函数。

在初始渲染期间,返回的状态(状态)与作为第一个参数(initialState)传递的值相同。

setState函数用于更新状态。它接受一个新的状态值并排队重新呈现组件。

请注意useState用于更新状态的挂钩回调的行为与组件不同this.setState。为了显示差异,我准备了两个示例。

const [state, setState] = useState(initialState);
Run Code Online (Sandbox Code Playgroud)
class UserInfoClass extends React.Component {
  state = { firstName: 'John', lastName: 'Doe' };
  
  render() {
    return <div>
      <p>userInfo: {JSON.stringify(this.state)}</p>
      <button onClick={() => this.setState({ 
        firstName: 'Jason'
      })}>Update name to Jason</button>
    </div>;
  }
}

// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
  const [userInfo, setUserInfo] = React.useState({ 
    firstName: 'John', lastName: 'Doe',
  });

  return (
    <div>
      <p>userInfo: {JSON.stringify(userInfo)}</p>
      <button onClick={() => setUserInfo({ firstName: 'Jason' })}>Update name to Jason</button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <UserInfoClass />
    <UserInfoFunction />
  </div>
, document.querySelector('#app'));
Run Code Online (Sandbox Code Playgroud)

setUserInfo使用回调时将创建新对象。请注意,我们丢失了lastName键值。为了解决这个问题,我们可以在内部传递函数useState

setUserInfo(prevState => ({ ...prevState, firstName: 'Jason' })
Run Code Online (Sandbox Code Playgroud)

参见示例:

<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>
Run Code Online (Sandbox Code Playgroud)
setUserInfo(prevState => ({ ...prevState, firstName: 'Jason' })
Run Code Online (Sandbox Code Playgroud)

与在类组件中找到的setState方法不同,useState不会自动合并更新对象。您可以通过将函数更新程序形式与对象传播语法结合使用来复制此行为:

setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});
Run Code Online (Sandbox Code Playgroud)

有关更多信息,useState请参见官方文档

  • 感谢您在示例中添加函数作为参数。 (2认同)

gec*_*kos 9

useState()是一个 React 钩子。钩子使在函数组件中使用状态和可变性成为可能。

虽然您不能在类中使用钩子,但您可以用函数 one 包装类组件并使用它的钩子。这是将组件从类迁移到函数形式的绝佳工具。这是一个完整的例子:

对于这个例子,我将使用一个计数器组件。就是这个:

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: props.count };
  }
  
  inc() {
    this.setState(prev => ({count: prev.count+1}));
  }
  
  render() {
    return <button onClick={() => this.inc()}>{this.state.count}</button>
  }
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
Run Code Online (Sandbox Code Playgroud)

它是一个简单的带有计数状态的类组件,状态更新是通过方法来完成的。这是类组件中非常常见的模式。首先是用一个同名的函数组件包装它,将它的所有属性委托给被包装的组件。您还需要在函数返回中呈现包装的组件。这里是:

function Hello(props) {
  class Hello extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: props.count };
    }

    inc() {
      this.setState(prev => ({count: prev.count+1}));
    }

    render() {
      return <button onClick={() => this.inc()}>{this.state.count}</button>
    }
  }
  return <Hello {...props}/>
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
Run Code Online (Sandbox Code Playgroud)

这是完全相同的组件,具有相同的行为、相同的名称和相同的属性。现在让我们将计数状态提升到函数组件。事情是这样的:

function Hello(props) {
  const [count, setCount] = React.useState(0);
  class Hello extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: props.count };
    }

    inc() {
      this.setState(prev => ({count: prev.count+1}));
    }

    render() {
      return <button onClick={() => setCount(count+1)}>{count}</button>
    }
  }
  return <Hello {...props}/>
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>
Run Code Online (Sandbox Code Playgroud)

注意方法inc还在,不会伤害任何人,实际上是死代码。这就是想法,只是保持提升状态。完成后,您可以删除类组件:

function Hello(props) {
  const [count, setCount] = React.useState(0);

  return <button onClick={() => setCount(count+1)}>{count}</button>;
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>

<div id='root'></div>
Run Code Online (Sandbox Code Playgroud)

虽然这使得在类组件中使用钩子成为可能,但我不建议你这样做,除非你像我在这个例子中所做的那样迁移。混合使用函数和类组件会使状态管理变得一团糟。我希望这有帮助

此致


Muh*_*eem 8

useState() 是一个内置的 React 钩子示例,它允许您在功能组件中使用状态。这在 React 16.7 之前是不可能的。

useState 函数是一个内置的钩子,可以从 react 包中导入。它允许您向功能组件添加状态。在函数组件中使用 useState 钩子,您可以在不切换到类组件的情况下创建一段状态。


Jan*_*łek 7

useStatehook 的语法很简单。

const [value, setValue] = useState(defaultValue)

如果您不熟悉此语法,请转到此处

我建议您阅读文档。其中有大量示例,所以有很好的解释。

import { useState } from 'react';

function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);
  
  // its up to you how you do it
  const buttonClickHandler = e => {
   // increment
   // setCount(count + 1)
   
   // decrement
   // setCount(count -1)
   
   // anything
   // setCount(0)
  }
  

  return (
       <div>
          <p>You clicked {count} times</p>
         <button onClick={buttonClickHandler}>
             Click me
         </button>
      </div>
   );
 }
Run Code Online (Sandbox Code Playgroud)


小智 6

谢谢 loelsonk,我这样做了

const [dataAction, setDataAction] = useState({name: '', description: ''});

    const _handleChangeName = (data) => {
        if(data.name)
            setDataAction( prevState  => ({ ...prevState,   name : data.name }));
        if(data.description)
            setDataAction( prevState  => ({ ...prevState,   description : data.description }));
    };
    
    ....return (
    
          <input onChange={(event) => _handleChangeName({name: event.target.value})}/>
          <input onChange={(event) => _handleChangeName({description: event.target.value})}/>
    )
Run Code Online (Sandbox Code Playgroud)


Asi*_*ora 5

Hooks 是React v16.7.0-alpha useState“Hook”中的一个新特性。useState()设置任何变量的默认值并在函数组件(PureComponent 函数)中进行管理。 ex : const [count, setCount] = useState(0);设置计数 0 的默认值。您可以使用setCounttoincrementdecrement该值。onClick={() => setCount(count + 1)}增加计数值。文件


Joh*_*edy 5

useState是React v16.8.0中可用的钩子之一。基本上,它使您可以将原本没有状态/功能的组件转换为可以具有自己状态的组件。

在最基本的级别上,它是通过以下方式使用的:

const [isLoading, setLoading] = useState(true);
Run Code Online (Sandbox Code Playgroud)

然后,这使您可以调用setLoading传递布尔值。这是拥有“有状态”功能组件的一种很酷的方法。