请注意,效果取决于updateUser,并且传递给useEffect的回调不会得到任何参数。下面是一个工作示例:
告诉我,我想重写用钩子上的生命周期方法编写的组件,但它并没有在这个地方出现,它没有正常工作。如何正确重写?
componentDidMount() {
this.updateUser();
}
componentDidUpdate(prevProps){
if (this.props.userId !== prevProps.userId) {
this.updateUser();
console.log('update')
}
}
updateUser = () => {
const {userId} = this.props;
if (!userId) {
return;
}
this.onUserLoading();
this.API
.getUser(userId)
.then(this.onUserLoaded)
.catch(this.onError)
我用react新钩子修改了
componentDidMount
表示useEffect(()=>{},[])
componentDidUpdate
表示useEffect((prev)=>{},[YOUR UPDATE DATA VARIABLE])
现在看起来是这样的,你的功能如下,
updateUser = () => {
if (!userId) {
return;
}
this.onUserLoading();
this.API
.getUser(userId)
.then(this.onUserLoaded)
.catch(this.onError)
}
这将被转换为功能部件
const [userId,setUserId] = useState(props.userId); // way 1
//const userId = {props}; // way 2
useEffect((prevProps)=>{
updateUser();
if(userId !== prevProps.userId){
updateUser();
console.log('update')
}
},[userId, updateUser])
const User = React.memo(function User({ userId }) {
const [userResult, setUserResult] = React.useState("");
//create this function only on mount
const onUserLoaded = React.useCallback(
(result) => setUserResult(result),
[]
);
//do not re create this function unless userId changes
const onUserLoading = React.useCallback(() => {
setUserResult(`user loading for ${userId}`);
setTimeout(
() => onUserLoaded(`result for user:${userId}`),
1000
);
}, [userId, onUserLoaded]);
//do not re create this function unless userId
// or onUserLoading changes, onUserLoading only
// changes when userId changes
const updateUser = React.useCallback(() => {
if (!userId) {
return;
}
onUserLoading();
}, [onUserLoading, userId]);
//run the effect when updateUser changes
// updateUser only changes when userId changes
React.useEffect(() => updateUser(), [updateUser]);
return <div>user result:{userResult}</div>;
});
const App = () => {
const [userId, setUserId] = React.useState(1);
return (
<div>
<button onClick={() => setUserId(userId + 1)}>
Change User ID
</button>
<User userId={userId} />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>