I am new to react and understanding react Hooks, i am creating a small application where I am Dynamically creating Bar using adding Div elements. For this Purpose I am using useRef() and UseEffect() to render after every change on the div element, though I know the initial value is set to null that is why it is returning unidentified value , i really want to understand how can i initialize or any workaround. Below is my Code
import React from "react";
import { useRef, useEffect, useState } from "react";
import "./ExpenseFilter.css";
const ExpenseFilter = (props) => {
const values = [100, 100, 340, 320, 500, 50, 45, 385, 95, 120, 90, 20];
const [refState, setrefState] = useState();
const ref = useRef();
useEffect(() => {
console.log(ref.current);
}, [refState]);
const drawChart = (data, padding) => {
const max = Math.max.apply(Math, data);
const chart = ref.current;
console.log(chart);
const barwidth =
(chart.offsetWidth - (values.length - 1) * padding - data.length * 10) /
data.length;
console.log(barwidth);
let left = 0;
for (let i in data) {
let newbar = document.createElement("div");
newbar.setAttribute("class", "bar");
newbar.style.width = barwidth + "px";
newbar.style.height = (data[i] / max) * 100 + "%";
newbar.style.left = left + "px";
chart.appendChild(newbar);
left += barwidth + padding + 10;
props.OnChangeDiv(newbar);
}
};
drawChart(values, 15);
return (
<div className="wrapper1">
<div className="select" tabIndex="1">
<input
className="selectopt"
name="test"
type="radio"
id="opt1"
checked
/>
<label for="opt1" class="option">
2019
</label>
<input className="selectopt" name="test" type="radio" id="opt2" />
<label for="opt2" class="option">
2020
</label>
<input className="selectopt" name="test" type="radio" id="opt3" />
<label for="opt3" class="option">
2021
</label>
<input className="selectopt" name="test" type="radio" id="opt4" />
<label for="opt4" class="option">
2022
</label>
<input className="selectopt" name="test" type="radio" id="opt5" />
<label for="opt5" class="option">
2023
</label>
</div>
<div
id="chart"
ref={(el) => {
setrefState(el);
}}
></div>
</div>
);
};
export default ExpenseFilter;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
thanks for looking into this, I solved this one myself. So as I said earlier the initial value that is assigned to useRef() was null we all know which is why the current property was being set to unidentified. what I did is I have placed a condition on the ref that if it is unidentified then it should return and used useState hooks to fire capture the states and once it changes in the state it fires the useEffect() to re-render the current state.
useEffect(() => {
if (!ref.current) {
return;
}
ref.current = refState;
console.log(ref.current);
}, [refState]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div
id="chart"
ref={(el) => {
ref.current = el;
setrefState(el);
}}
></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
using the next State if the ref.