我正在尝试将带有 this.setstate 回调的简单 React 组件转换为带有 useState/useEffect 的功能组件,但我无法使用后者重现相同的功能。
我正在使用一个简单的警报/通知系统示例来在超时后附加和删除警报。沙盒在这里:
https://codesandbox.io/s/class-and-function-callback-comparison-54tus?file=/src/index.js
用于对比的相关代码:
const NoticesWithFunctionCallback = () => {
const [state, setState] = useState({
alerts: [],
show: false
});
const addNotice = (e) => {
setState({
alerts: [...state.alerts, ""]
});
};
useEffect(() => {
(async () => {
await timeout(3000);
console.log("timeout occurred");
const newAlerts = tail([...state.alerts]);
setState({
alerts: newAlerts
});
})();
}, [state.alerts]);
return (
<div className="App">
<h3>
Notices using function component with UseState and UseEffect callback
</h3>
<Generator addNotice={addNotice} />
<Container>
{state.alerts.map((item, index) => (
<Alert>some alert here</Alert>
))}
</Container>
</div>
);
};
class NoticesWithClassCallback extends React.Component {
state = {
alerts: [],
show: false
};
addNotice = (e) => {
this.setState(
{
alerts: [...this.state.alerts, ""]
},
async () => {
await timeout(3000);
console.log("timeout occurred");
const newAlerts = tail([...this.state.alerts]);
this.setState({
alerts: newAlerts
});
}
);
};
render() {
return (
<div className="App">
<h3>Notices using class component and setState callback</h3>
<Generator addNotice={this.addNotice} />
<Container>
{this.state.alerts.map((item, index) => (
<Alert>some alert here</Alert>
))}
</Container>
</div>
);
}
}
我希望就如何使用 usestate/useeffect 用函数组件替换正确运行的类组件 setstate 回调组件提供建议。
欢迎提出任何建议。
答案 0 :(得分:0)
这里不需要useEffect。每次更改警报数组时都会触发 useEffect:通过向其中添加项目以及删除。它也在初始化后立即触发,所以事情变得一团糟。相反,您应该像这样修改 addNotice 函数并使用前一个更新状态:
const NoticesWithFunctionCallback = () => {
const [state, setState] = useState({
alerts: [],
show: false
});
const addNotice = (e) => {
setState({
...state,
alerts: [...state.alerts, '']
});
(async () => {
await timeout(3000);
setState(prevState => {
return {
...prevState,
alerts: [...tail([...prevState.alerts])]
}
});
})()
};
return (
<div className="App">
<h3>
Notices using function component with UseState and UseEffect callback
</h3>
<p>I want this to replicate the class component but its broken...</p>
<Generator addNotice={addNotice} />
<Container>
{state.alerts.map((item, index) => (
<Alert key={index}>Alert</Alert>
))}
</Container>
</div>
);
};
答案 1 :(得分:-1)
从类到功能组件有一些步骤:
第一步:
class NameOfComponent extends Component
变成
function NameOfComponent(props){
第 2 步:删除 constructor
第 3 步:删除 render()
方法,保留 return
步骤 4. 在所有方法前添加 const
第 5 步:删除整个组件中的 this.state
步骤 6。删除整个组件中对“this”的所有引用
第 7 步:使用 useState()
设置初始状态(并从“react”导入)
数字示例:
const [count, setCount] = useState(0) // the useState() param is the initial value
对象示例:
const [form, setValues] = useState({
id: 0,
first: ‘’,
last: ‘’,
password: ‘’,
subscribe: false
})
第 8 步: - 通过您定义的 setter 更改 this.setState()
(例如 setValues 或第 7 步中的 setCount)
this.setState({ count: this.state.count + 1 )}
会变成 setCount(count+1)
第 9 步:将 componentDidMount
替换为 useEffect
useEffect(() => {
fetch(‘url’)
.then(res => res.json())
.then(items => setSomething(items)
.catch(console.log(err))
}, [])
第 10 步:用 useEffect 替换 componentDidUpdate 或 componentWillReceiveProps
useEffect(() => {
console.log(myPropsToCheck+ " has changed ! ")
}, [myPropsToCheck])
})