1 javascript reactjs react-hooks
每当某个状态或道具更新时,我都试图使用 useEffect 来更新 DOM。当我希望 DOM 更新触发时,控制台会记录我的测试,但 DOM 更新或渲染从未发生
我试图找出制作条件语句的方法,以检查我希望 useEffect 触发的道具或状态是否已更改,但由于该函数正在运行我的控制台日志,而不是我的渲染,因此必须有我缺少的东西。
import React, { useEffect } from 'react';
function Report( { weatherData, units }) {
let windUnits = 'mph';
useEffect(() => {
units == 'imperial' ? windUnits = 'mph' : windUnits = 'km/h';
console.log('units updated');
}, [ weatherData ]);
return (
<p id="wind">{ `${ weatherData.wind.speed }${ windUnits } ${ getWindDirection(weatherData.wind.deg) }`}</p>
)
}
export default Report;
Run Code Online (Sandbox Code Playgroud)
单位来自父组件,可以通过两个按钮更改以接收不同的测量数据。weatherData 是从 api 接收到的数据,当调用 api 并且数据发生变化时,windUnits 应根据指定的单位类型发生变化。
目前,虽然 console.log 工作并且正确的单元类型从父组件打印到控制台,但屏幕上的文本不会更改以匹配它。
由于每当 props ( weatherData, units) 更改时都会重新渲染组件,因此您不需要使用效果。只需将正确的单位分配给windUnits:
const { useState } = React;
const getWindDirection = x => x;
const Report = ({ weatherData, units }) => {
const windUnits = units == 'imperial' ? 'mph' : 'km/h';
return (
<p id="wind">{ `${ weatherData.wind.speed }${ windUnits } ${ getWindDirection(weatherData.wind.deg) }`}</p>
);
};
const Demo = () => {
const [units, setUnits] = useState('imperial');
return (
<div>
<button onClick={() => setUnits('imperial')}>imperial</button>
<button onClick={() => setUnits('metric')}>metric</button>
<Report weatherData={{ wind: { speed: 10, deg: 45 }}} units={units} />
</div>
)
};
ReactDOM.render(
<Demo />,
demo
)Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>Run Code Online (Sandbox Code Playgroud)
如果您只想在windData更改时重新渲染组件,则可以使用useEffectwith useState。useEffect处理副作用,不重新渲染组件,对变量的更改将在下次渲染时丢失。useState另一方面将重新渲染组件。
const { useState, useEffect } = React;
const getWindDirection = x => x;
const Report = ({ weatherData, units }) => {
const [windUnits, setWindUnits] = useState('mph');
useEffect(() => {
setWindUnits(units == 'imperial' ? 'mph' : 'km/h');
}, [weatherData]);
return (
<p id="wind">{ `${ weatherData.wind.speed }${ windUnits } ${ getWindDirection(weatherData.wind.deg) }`}</p>
);
};
const windData = { wind: { speed: 10, deg: 45 }};
const Demo = () => {
const [units, setUnits] = useState('imperial');
const [data, setData] = useState(windData);
const changeSpeed = () => setData({ ...data, wind: { ...data.wind, speed: Math.random() * 100 }});
return (
<div>
<button onClick={() => setUnits('imperial')}>imperial</button>
<button onClick={() => setUnits('metric')}>metric</button>
<button onClick={changeSpeed}>Change speed</button>
<Report weatherData={data} units={units} />
</div>
)
};
ReactDOM.render(
<Demo />,
demo
)Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>Run Code Online (Sandbox Code Playgroud)
另一种选择是在回调中使用React.memoareEqual,并且只检查weatherData相等性:
const { useState, memo } = React;
const getWindDirection = x => x;
const Report = memo(({ weatherData, units }) => {
const windUnits = units == 'imperial' ? 'mph' : 'km/h';
return (
<p id="wind">{ `${ weatherData.wind.speed }${ windUnits } ${ getWindDirection(weatherData.wind.deg) }`}</p>
);
}, ({ weatherData: prev }, { weatherData: current }) => prev === current);
const windData = { wind: { speed: 10, deg: 45 }};
const Demo = () => {
const [units, setUnits] = useState('imperial');
const [data, setData] = useState(windData);
const changeSpeed = () => setData({ ...data, wind: { ...data.wind, speed: Math.random() * 100 }});
return (
<div>
<button onClick={() => setUnits('imperial')}>imperial</button>
<button onClick={() => setUnits('metric')}>metric</button>
<button onClick={changeSpeed}>Change speed</button>
<Report weatherData={data} units={units} />
</div>
)
};
ReactDOM.render(
<Demo />,
demo
)Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4336 次 |
| 最近记录: |