是否可以使用function
作为我的 React 组件的状态?
此处的示例代码:
// 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
?
可以使用钩子将函数设置为状态,但由于状态可以使用返回初始状态或更新状态的函数进行初始化和更新,因此您需要提供一个函数,该函数又返回要置于状态的函数。
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>
TL;博士
是的,可以使用函数作为 React 组件的状态。为此,您必须使用一个返回函数的函数React.useState
:
const [ooops, setOoops] = React.useState<OoopsFunction>(
() => () => console.log('default ooops')
);
// or
const yourFunction = () => console.log('default ooops');
const [ooops, setOoops] = React.useState<OoopsFunction>(
() => yourFunction
);
要更新函数,您还必须使用返回函数的函数:
setOoops(() => () => console.log("other ooops"));
// or
const otherFunction = () => console.log("other ooops");
setOoops(() => otherFunction);
详细答案
关于React.useState
的注意事项
React 中带有类型的useState
签名是
function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
它表明,有两种方法可以在您的状态中设置初始值:
- 按原样提供初始值 (
React.useState(0)
- 初始值0
), - 提供一个函数,该函数返回要设置的初始值(
React.useState(() => 0)
- 初始值也0
)。
重要提示:如果在React.useState
中提供函数,则在执行React.useState
时执行此函数,并且返回值存储为初始状态。
如何实际存储函数
这里的问题是,如果要将函数存储为状态,则不能按原样将其作为初始状态提供,因为这会导致函数被执行,并且其返回值存储为状态而不是函数本身。因此,当您编写时
const [ooops, setOoops] = React.useState<OoopsFunction>(
() => console.log('default ooops')
);
调用React.useState
并存储返回值(在本例中为undefined
)时,会立即记录'default ooops'
。
这可以通过提供一个高阶函数来避免,返回你想要存储的函数:
const [ooops, setOoops] = React.useState<OoopsFunction>(
() => () => console.log('default ooops')
);
这样,外部函数将在首次运行React.useState
时肯定会执行,并且其返回值将被存储。由于此返回值现在是必需的函数,因此将存储此函数。
关于状态设置器函数的说明
状态设置器函数的(此处setOoops
)签名为
Dispatch<SetStateAction<S>>
跟
type Dispatch<A> = (value: A) => void;
type SetStateAction<S> = S | ((prevState: S) => S);
与React.useState
一样,还可以使用值或返回值的函数更新状态。因此,为了更新状态,还必须使用上面的高阶函数。
前面的答案使我走上了正确的轨道,但是我需要稍微调整我的setState参数,因为我想执行一个带有参数的函数。 以下内容对我有用!
const [handler, setHandler] = useState(() => {});
setHandler(() => () => enableScheduleById(scheduleId));