1

I'm creating a react app with a method to draw some arrows among divs. The function doesn't produce arrows right away returns the JSX but just after I manually re-render the DOM by scrolling the page or do a route change. How can I force render the DOM after the return of the function?

drawArrows = () => {
        const questionsList = this.state.questionsData;
        return questionsList.map(each =>
            <Arrow
                key={each.order}
                fromSelector={`#option${each.order}`}
                fromSide={'right'}
                toSelector={`#q${each.order}`}
                toSide={'left'}
                color={'#ff6b00'}
                stroke={3}
            />
        );
    }

render (){
    return(
       ...code
       {this.drawArrows()}
    )
}
8
  • this.state.questionsData a populated array when the component first renders? I don't see any issue with this code. Commented Jan 27, 2021 at 10:09
  • @DrewReese yes it's a populated array. The issue is I can't put a force render method (a setState or a forceUpdate) after the render method of the function Commented Jan 27, 2021 at 10:31
  • if you map directly from this.state.questionsData instead of assigning first to questionsList ? Or directly inline ? does it work better ? Commented Jan 27, 2021 at 10:43
  • 1
    If your state is populated then I see no reason for that drawArrows function not to return JSX to be rendered. Are you sure it's populated at the time? Are you doing some state mutation elsewhere in the component? Can you provide a more complete component code example? Pretty much any time you get to a point where you think you need to "force react to render" you've done something wrong. Commented Jan 27, 2021 at 10:46
  • 2
    Console logs can be a bit tricky as they are asynchronous in nature. Can you include a better code example? Could you also try distilling your code down to a minimal, reproducible example running in a codesandbox that we could debug in? Often you will find that when creating a minimal example your bug/issue will become very apparent. Commented Jan 27, 2021 at 10:52

1 Answer 1

1

you can do it easy with functional Component with useState and useEffect

import { useState } from 'react';
const ComponentName = () => {
const [arow, setArow] = useState();
const [questionsData, setQuestionsData] = useState([]);
const drawArrows = () => questionsData.map(each =>
    <Arrow
        key={each.order}
        fromSelector={`#option${each.order}`}
        fromSide={'right'}
        toSelector={`#q${each.order}`}
        toSide={'left'}
        color={'#ff6b00'}
        stroke={3}
    />
);
useEffect(() => {
    setArow(drawArrows())
}, [])
return (
    { arow }
)

}
Sign up to request clarification or add additional context in comments.

1 Comment

Storing React components in component state is a sure-fire way to introduce stale enclosures, it's an anti-pattern. Store the data and generate the view from state when rendering. Also, the effect with empty dependency will run only once when the component mounts and the questionsData state is an empty array, so nothing will be rendered on the initial render cycle, and nothing will be rendered on any subsequent render cycles.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.