0

I have a parent component, that render one child component several time. This child component is used in many different components. I need to have an array in this child component that keeps all the previous renders of the component, then get access to the largest text passed to it.

import TextComponent from '../../text'
const ParentComponent = ()=>{
  // ... some code here and get some data from API
 const text = getTextFromAPI()
  return (
   <>
    <ARandomComponent/>
    <AnotherRandomComponent/>
    <TextComponent text={text}/>
  </>)
}

In the TextComponent I need to know what text each element received, and return the largest text. I thought maybe I can have an array inside TextComponent but of course with each render, component has fresh data and I know this is by design.

Is there any way to active this? To store a value in the TextComponent that other renders from different places still have access to that value

6
  • If I understood you correctly, you want to share some state between all instances of the TextComponent? In such case, store the array as state in the parent component. Commented Dec 7, 2021 at 11:01
  • The problem is that there are several parents. This TextComponent is getting used in 15 different parent components, I don't want to duplicate the logic in each parent component, and that's why I was looking for a way to implement it inside the TextComponent @zhulien Commented Dec 7, 2021 at 11:05
  • @Jax-p I think you did not correctly understand what I meant. The TextComponent is getting rendered in 15 different places, and I don't want to place the logic in the parent components. But I need the TextComponent itself keep track of its other instances Commented Dec 7, 2021 at 11:07
  • A different instance of the component will be used in each component that use TextComponent. It's not like a global component that any component can refer to. What you can do is using a context that each of the TextComponent will be connected to via a hook and that way you can communicate with all the TextComponent components. But then again, I'm not sure whether I understood correctly. Commented Dec 7, 2021 at 11:13
  • @Beekman In such case, you should either store the shared state in a context (check out reactjs.org/docs/context.html) or a custom service and fetch the data in your TextComponents from there. Commented Dec 7, 2021 at 11:18

2 Answers 2

1

If your ParentComponent isn't re-rendering. You could use a useState with a condition on calling your setState that the actual state is smaller than the new text you're gonna receive.

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

2 Comments

No, actually the problem is not about re-rendering only. It's about the TextComponent getting rendered in 15 different parent components. It's a shared component, and I want it to be standalone and work by itself and know the longest text passed to it without duplicating the logic in several parent components
Then inside your TextComponent use a useState to keep your data and use a useEffect with your text prop in the dependency array. Do your logic here to see if you got the largest string or not and update the state
0

Edit: You clarified in a comment the requirement for a "global" value used by multiple components. This is a case for using the builtin Context API or a state management library like Recoil or Effector.


You can use a hook like this to store the longest string seen during the lifespan of the component which used it:

function useLongestString (text = '') {
  const [str, setStr] = useState(text);
  if (text.length > str.length) setStr(text);
  return str;
}

Demo:

<div id="root"></div><script src="https://unpkg.com/[email protected]/umd/react.development.js"></script><script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script><script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
<script type="text/babel" data-type="module" data-presets="react">

const {useState} = React;

function useLongestString (text = '') {
  const [str, setStr] = useState(text);
  if (text.length > str.length) setStr(text);
  return str;
}

function DisplayLongestString (props) {
  const longest = useLongestString(props.text);
  return <div>{longest}</div>;
}

function Example (): ReactElement {
  const [value, setValue] = useState('Keep typing');
  return (
    <div>
      <h2>Longest string:</h2>
      <DisplayLongestString text={value} />
      <input
        onChange={ev => setValue(ev.target.value)}
        placeholder="Type a longer string"
        value={value}
      />
    </div>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));

</script>

2 Comments

This would not work as he'll need to use the hook arbitrary number of times and each usage creates its own brand new state which is independent of the other usages.
@zhulien Thanks for making me aware of something that wasn't written in the question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.