Atu*_*tul 8 reactjs react-hooks
我正在使用带有挂钩的功能组件。我需要从孩子那里更新父母的状态,并且我正在使用父母的道具功能。一切正常,除了我的prop函数获取最后一个状态,而不是当前状态,因为在useState钩子设置当前状态之前执行我的prop函数。我该如何等待useState调用之后执行我的回调函数。我正在寻找类似我们正在使用setState(state,callback)作为第二个参数的东西。下面是相同的代码片段。
function Parent() {
const [Name, setName] = useState("");
getChildChange = getChildChange.bind(this);
function getChildChange(value) {
setName(value);
}
return <div> {Name} :
<Child getChildChange={getChildChange} ></Child>
</div>
}
function Child(props) {
const [Name, setName] = useState("");
handleChange = handleChange.bind(this);
function handleChange(ele) {
setName(ele.target.value);
props.getChildChange(collectState());
}
function collectState() {
return Name;
}
return (<div>
<input onChange={handleChange} value={Name}></input>
</div>);
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*uch 110
您可以使用 useEffect/useLayoutEffect 来实现这一点:
const SomeComponent = () => {
const [count, setCount] = React.useState(0)
React.useEffect(() => {
if (count > 1) {
document.title = 'Threshold of over 1 reached.';
} else {
document.title = 'No threshold reached.';
}
}, [count]);
return (
<div>
<p>{count}</p>
<button type="button" onClick={() => setCount(count + 1)}>
Increase
</button>
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
更多关于它在这里。
如果您正在寻找开箱即用的解决方案,请查看这个自定义钩子,它的工作方式类似于 useState 但接受回调函数作为第二个参数:
// npm install use-state-with-callback
import useStateWithCallback from 'use-state-with-callback';
const SomeOtherComponent = () => {
const [count, setCount] = useStateWithCallback(0, count => {
if (count > 1) {
document.title = 'Threshold of over 1 reached.';
} else {
document.title = 'No threshold reached.';
}
});
return (
<div>
<p>{count}</p>
<button type="button" onClick={() => setCount(count + 1)}>
Increase
</button>
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
for*_*d04 68
setState(updater, callback) 为了 useState以下实现非常接近于setState类的原始回调。
对接受的答案所做的改进:
setState调用的回调都可以是动态的,就像类一样const App = () => {
const [state, setState] = useStateCallback(0); // same API as useState
const handleClick = () => {
setState(
prev => prev + 1,
// second argument is callback, `s` being the *updated* state
s => console.log("I am called after setState, state:", s)
);
};
return <button onClick={handleClick}>Increment</button>;
}
Run Code Online (Sandbox Code Playgroud)
useStateCallbackfunction useStateCallback(initialState) {
const [state, setState] = useState(initialState);
const cbRef = useRef(null); // init mutable ref container for callbacks
const setStateCallback = useCallback((state, cb) => {
cbRef.current = cb; // store current, passed callback in ref
setState(state);
}, []); // keep object reference stable, exactly like `useState`
useEffect(() => {
// cb.current is `null` on initial render,
// so we only invoke callback on state *updates*
if (cbRef.current) {
cbRef.current(state);
cbRef.current = null; // reset callback after execution
}
}, [state]);
return [state, setStateCallback];
}
Run Code Online (Sandbox Code Playgroud)
更多信息:React Hooks 常见问题解答:是否有类似实例变量的东西?
const App = () => {
const [state, setState] = useStateCallback(0); // same API as useState
const handleClick = () => {
setState(
prev => prev + 1,
// second argument is callback, `s` being the *updated* state
s => console.log("I am called after setState, state:", s)
);
};
return <button onClick={handleClick}>Increment</button>;
}
Run Code Online (Sandbox Code Playgroud)
function useStateCallback(initialState) {
const [state, setState] = useState(initialState);
const cbRef = useRef(null); // init mutable ref container for callbacks
const setStateCallback = useCallback((state, cb) => {
cbRef.current = cb; // store current, passed callback in ref
setState(state);
}, []); // keep object reference stable, exactly like `useState`
useEffect(() => {
// cb.current is `null` on initial render,
// so we only invoke callback on state *updates*
if (cbRef.current) {
cbRef.current(state);
cbRef.current = null; // reset callback after execution
}
}, [state]);
return [state, setStateCallback];
}
Run Code Online (Sandbox Code Playgroud)
Abh*_*mar 25
在 React16.x 及更高版本中,如果您想使用useState钩子在状态更改时调用回调函数,您可以使用useEffect附加到状态更改的钩子。
import React, { useEffect } from "react";
useEffect(() => {
props.getChildChange(name); // using camelCase for variable name is recommended.
}, [name]); // this will call getChildChange when ever name changes.
Run Code Online (Sandbox Code Playgroud)
实际上,this在使用 react hooks 时应该避免使用。它会导致副作用。这就是为什么 react team create react hooks。
如果删除代码的尝试绑定this,你可以简单地传递setName的Parent到Child,并调用它handleChange。更干净的代码!
function Parent() {
const [Name, setName] = useState("");
return <div> {Name} :
<Child setName={setName} ></Child>
</div>
}
function Child(props) {
const [Name, setName] = useState("");
function handleChange(ele) {
setName(ele.target.value);
props.setName(ele.target.value);
}
return (<div>
<input onChange={handleChange} value={Name}></input>
</div>);
}
Run Code Online (Sandbox Code Playgroud)
此外,您不必创建两个副本Name(一个 inParent另一个 in Child)。坚持“Single Source of Truth”原则,Child不必拥有状态,Name而是从Parent. 更清洁的节点!
function Parent() {
const [Name, setName] = useState("");
return <div> {Name} :
<Child setName={setName} Name={Name}></Child>
</div>
}
function Child(props) {
function handleChange(ele) {
props.setName(ele.target.value);
}
return (<div>
<input onChange={handleChange} value={props.Name}></input>
</div>);
}
Run Code Online (Sandbox Code Playgroud)
小智 7
我们可以编写自定义函数,如果状态发生任何变化,它将调用回调函数
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const useStateCallbackWrapper = (initilValue, callBack) => {
const [state, setState] = useState(initilValue);
useEffect(() => callBack(state), [state]);
return [state, setState];
};
const callBack = state => {
console.log("---------------", state);
};
function App() {
const [count, setCount] = useStateCallbackWrapper(0, callBack);
return (
<div className="App">
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+</button>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)
`
小智 6
另一种实现此目的的方法是:
const [Name, setName] = useState({val:"", callback: null});
React.useEffect(()=>{
console.log(Name)
const {callback} = Name;
callback && callback();
}, [Name]);
setName({val:'foo', callback: ()=>setName({val: 'then bar'})})Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15958 次 |
| 最近记录: |