reactjs - Handling state react native
问题描述
This is my picker with a linechart(LChart) component.
<Picker selectedValue = {this.state.value}
onValueChange = {this.onValueChange}
>
<Picker.Item value='' label='Select Device...' />
{devices.map((s, i) => {
return (<Picker.Item label={s} value={s} key={i}/>)
})}
</Picker>
<LChart data={Fdata} title={"LineChart"}/>
I have an array of devices to feed into picker and with every onValuechange i want to show the linechart of respective device. My onValueChange function:
onValueChange = async(value) => {
this.setState({ value: value })
this.interval = setInterval(() => {
var Fdata = [];
fetch('http://ec2-137.compute-1.amazonaws.com:3009/chart/unitID', {
method: 'post',
headers:{
'Accept': 'application/json',
'Content-type': 'application/json'
},
body:JSON.stringify({
unitID: value,
}) })
.then((response) => response.json())
.then((responseJson) => {
responseJson.forEach(function (vol) {
Fdata.push({
value: vol.voltage,
date: new Date(vol.time),
});
});
if (this._isMounted) {
this.setState({
Fdata: Fdata,
});
}
})
}, 5000);
}
my issue here is when i initially select a device from picker, the line chart shows up perfect and reloads according to my set interval. But when i select a different device from the picker, the line chart started to toggle between first and second device data and same continues with 3 rd selection and so on.
I guess i am not handling the state properly. Any help will be appreciated. Thanks a ton.
解决方案
您需要清理间隔。现在,您只需继续创建额外的间隔来 ping 设备。您可以做的一件事是创建一个useEffect
将在所选设备更改后清除间隔。下面的示例使用占位符,但您应该能够看到大致的想法。
const {useState, useEffect, Fragment} = React;
const Chart = ({deviceData}) => {
return (
<div>
{deviceData ? (
<Fragment>
<div>Date fetched: {Date.now()}</div>
<pre><code>{JSON.stringify(deviceData, null, 4)}</code></pre>
</Fragment>
) : (
<p>Waiting for device</p>
)}
</div>
);
};
const App = () => {
const [selectedDevice, setSelectedDevice] = useState("");
const [deviceAttrs, setDeviceAttrs] = useState();
useEffect(() => {
if (!selectedDevice) return;
const interval = setInterval(() => {
fetch(`http://jsonplaceholder.typicode.com/todos/${selectedDevice}`)
.then(res => res.json())
.then(data => setDeviceAttrs(data));
}, 5000);
return () => clearInterval(interval);
}, [selectedDevice]);
const options = [1, 2, 3];
return (
<div>
<select onChange={e => setSelectedDevice(e.target.value)}>
<option value="">Please select a device</option>
{options.map(option => (
<option key={option} value={option}>Device {option}</option>
))}
</select>
{selectedDevice ? (
<Chart deviceData={deviceAttrs} />
) : (
<div>Please select a device</div>
)}
</div>
);
};
ReactDOM.render(<App />, document.getElementById("app"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="app"></div>
推荐阅读
- acumatica - 如何将 acumatica msdl 文件添加到云?
- sql-server - 从开始时间获取每小时数据
- css - WordPress(标题/导航栏)上同一图像的不同背景位置以及如何使它们相同?
- javascript - javascript innerhtml 显示为文本
- python - 如何在目录中的多个文件名中查找和替换两个不同的字符串?
- sql - 动态 SQL 转换文本和图像
- syntax - <> 在飞镖类扩展后的含义
- javascript - 停止 Axios 承诺链
- javascript - 用输出参数包装一个 c++ 函数,以便在 javascript/node 中使用
- woocommerce - 产品页面中的 Woo Commerce 产品图片太大。