Home > Back-end >  Setting function in state variables, but useEffect shows them as undefined
Setting function in state variables, but useEffect shows them as undefined

Time:07-31

I am trying to build a bar chart from some statistical data using d3 and react. I am passing statistical data as data prop, and then in useEffect for deps data, I am calling createScales to get xscale and yscale respectively, and setting them up in state variables scaleX and scaleY, respectively. But when I run useEffect on deps [scaleX,scaleY], there typeof prints undefined.

Pasting code snippet :-

function BarChart({
  data = [],
  barWidth = 14
}) {
    const createScales = () => {
    const _xScale = d3.scaleBand()....
    const _yScale = d3.scaleLinear()....
    console.log(typeof _xScale, typeof _yScale, " scales ordered") //printed as line 29 in console below
    return [_xScale, _yScale]
  }

  const [scaleX, setScalX] = useState(undefined)
  const [scaleY, setScalY] = useState(undefined)
  
  useEffect(() => {
    const [x, y] = createScales()
    console.log(typeof scaleX, typeof scaleY, "scales before change when change scale called") //printed as line 107
    console.log(typeof x, typeof y, "scales from order") //printed as line 112
    setScalX(x)
    setScalY(y)
  }, [data])
  

  useEffect(() => {
    console.log("useEffect called ", typeof scaleX, typeof scaleY) //printed as line 118
    const [xAxisCall, yAxisCall] = createAxes()
    if (xAxisCall && yAxisCall) {
      {{chartDrawing logic}}
    }
  }, [scaleX, scaleY])

}

The console prints are as follows => x, y are functions inside createScales() and these are set in state on data change (112th line), but in useEffect for scaleX and scaleY we get their typeof as undefined. Pls note that i am not callin setScalX or setScalY anywhere else in component, is it some sideEffect of d3 ? :-

VM2278:236 
bar-chart.js:29 function function  scales ordered
bar-chart.js:107 undefined undefined scales before change when change scale called
bar-chart.js:112 function function scales from order
bar-chart.js:118 useEffect called  undefined undefined
bar-chart.js:29 function function  scales ordered
bar-chart.js:107 undefined undefined scales before change when change scale called
bar-chart.js:112 function function scales from order
bar-chart.js:118 useEffect called  undefined undefined

CodePudding user response:

This is an unfortunate and confusing issue when passing a function to be stored in state. When the setX state updater function is passed a function it is interpreted to be an updater function, and when the React state update is processed is invoked and the function's return value is returned as the state's next value. In this case it seems the x and y functions are void returns.

To resolve, pass a function that returns the x and y functions you want to store in state.

Example:

useEffect(() => {
  const [x, y] = createScales();

  setScalX(() => x);
  setScalY(() => y);
}, [data]);

Edit setting-function-in-state-variables-but-useeffect-shows-them-as-undefined

  • Related