是否可以在React中使用React.useState(()=> {})?

时间:2019-04-10 20:57:14

标签: reactjs typescript default-value react-hooks

是否可以使用function作为我的React Component的状态?

示例代码在这里:

// typescript 
type OoopsFunction = () => void;

export function App() {
    const [ooops, setOoops] = React.useState<OoopsFunction>(
        () => console.log('default ooops')
    );

    return (
        <div>
            <div onClick={ ooops }>
                Show Ooops
            </div>

            <div onClick={() => {
                setOoops(() => console.log('other ooops'))
            }}>
                change oops
            </div>
        </div>
    )
}

但是它不起作用... defaultOoops会在一开始被调用,并且当单击change oops时,otrher ooops将立即登录到控制台,而不是单击后登录再次Show Ooops

为什么?

我可以使用函数作为组件的状态吗?

还是React有其特殊的方式来处理the function state

3 个答案:

答案 0 :(得分:0)

可以使用钩子将功能设置为状态,但是由于可以使用返回初始状态或更新状态的功能来初始化和更新状态,因此您需要提供一个功能,该功能又可以返回所需的功能进入状态。

const { useState } = React;

function App() {
  const [ooops, setOoops] = useState(() => () => console.log("default ooops"));

  return (
    <div>
      <button onClick={ooops}>Show Ooops</button>

      <button
        onClick={() => {
          setOoops(() => () => console.log("other ooops"));
        }}
      >
        change oops
      </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>

答案 1 :(得分:0)

在React中useState的实现是

export function useState<S>(initialState: (() => S) | S) {
  const dispatcher = resolveDispatcher();
  return dispatcher.useState(initialState);
}

它表明,您确实可以使用函数作为参数,并且该函数必须返回类型S。在您的情况下,Sundefined,因为() => console.log(...)不返回任何内容,尽管您将其明确指定为OoopsFunction ,但

因此,如果您想通过useState将函数存储为状态,则必须实现Tholle的方法,该函数实际上返回一个函数而不是undefined

答案 2 :(得分:0)

之前的答案让我走上了正确的道路,但我需要稍微调整我的 setState 参数,因为我想执行一个带有参数的函数。以下对我有用!

const [handler, setHandler] = useState(() => {});

setHandler(() => () => enableScheduleById(scheduleId));