We are making a crypto trading calculator and I am struggling with a React rerendering issue because my React knowledge is somewhat limited and I don’t have lots of practice.
There are 10 calculator inputs on the page, one drop-down menu (implemented via React Select) for the selection of any crypto coin by the user, and one chart widget from TradingView implemented via https://www.npmjs.com/package/react-ts-tradingview-widgets.
The idea is that the user selects the coin of their preference via the drop-down menu, triggering the TradingView chart rerendering to show the chart of the coin that the user chose.
Everything works well, however the chart is rerendering every time that any state changes on the page. And with 10 inputs for calculations it happens very often, sometimes a couple of times per second.
So I’d like the chart to rerender only upon the selection of a new coin by the user, which is represented by state symbol, which is defaulted to BTC upon mounting.
const [symbol, setSymbol] = useState('BTCUSDT');
Here’s the TradingView widget chart
<div className="mx-4 mb-14 mt-4 w-full xl:w-1/2 h-72 xl:pr-3 mb-4 mx-0 mt-0 md:w-full lg:px-3 md:px-1 px-3">
<AdvancedRealTimeChart theme="dark" symbol={symbol} interval="60" autosize </AdvancedRealTimeChart>
</div>
I was wondering if it’s possible to use useEffect hook in order to make it rerender only upon symbol state change. Maybe something like this?
useEffect(() => {
const widgetChart = <div className="mx-4 mb-14 mt-4 w-full xl:w-1/2 h-72 xl:pr-3 mb-4 mx-0 mt-0 md:w-full lg:px-3 md:px-1 px-3">
<AdvancedRealTimeChart theme="dark" symbol={symbol} interval="60" autosize </AdvancedRealTimeChart>
</div>
}, [symbol])
And then placing {widgetChart} in the JSX?
Or maybe by creating a function and then running it inside useEffect and placing it in JSX?
function returnWidget() {
return ( <div className="mx-4 mb-14 mt-4 w-full xl:w-1/2 h-72 xl:pr-3 mb-4 mx-0 mt-0 md:w-full lg:px-3 md:px-1 px-3">
<AdvancedRealTimeChart theme="dark" symbol={symbol} interval="60" autosize></AdvancedRealTimeChart>
</div>
)
}
useEffect(() => {
returnWidget()
}, [symbol])
And I think I can use something like React.memo(). What would be the most modern and easiest way to do this? Thanks a lot everyone!
Finally managed to resolve this and I was on the right path before. It can be done using useEffect hook really easily just like I previously proposed.
useEffect(() => {
const widgetChart = <div className="mx-4 mb-14 mt-4 w-full xl:w-1/2 h-72 xl:pr-3 mb-4 mx-0 mt-0 md:w-full lg:px-3 md:px-1 px-3">
<AdvancedRealTimeChart theme="dark" symbol={symbol} interval="60" autosize </AdvancedRealTimeChart>
</div>
}, [symbol])
All you need to do apart from that is to add state, set it to widgetChart inside the hook, and then simply place the {widgetChart} in the JSX where it should be displayed.
const [chart, setChart] = useState(null);
useEffect(() => {
const widgetChart = (
<div className="mx-4 mb-14 mt-4 w-full xl:w-1/2 h-72 xl:pr-3 mb-4 mx-0 mt-0 md:w-full lg:px-3 md:px-1 px-3">
<AdvancedRealTimeChart theme="dark" symbol={symbol} interval="60" autosize />
</div>
);
setChart(widgetChart);
}, [symbol]);