user18113903
user18113903

Reputation:

is it possible to change the useState value without rendering? React

I need to change the useState without rendering the page.

First is it possible?

const UsersComponent = ({valueProp}) => {

const [users, setUsers] = useState(valueProp);
const [oldUsers, setoldUsers] = useState(value);

  const allUsers = useSelector((state) =>
    state.users
  );

  useEffect(() => {
    dispatch(getUsersData());
  }, [dispatch]);

  useEffect(() => {
    // assign users to state oldUsers
  }, [dispatch]);


  const onClickMergeTwoArrayOfUsers = () => {
    let oldUsers = collectData(oldUsers);
    const filteredUsers = intersectionBy(oldUsers, valueProp, "id"); 

     setUsers(filteredUsers); // most important
     console.log("filteredUsers", filteredUsers);  // not changed
  };

I tried everything nothing helps me.

  useEffect(() => {
        let oldUsers = collectData(oldUsers);
        const filteredUsers = intersectionBy(oldUsers, valueProp, "id"); 
 
       setUsers(filteredUsers); // most important
  }, [users]); // RETURN INFINITIVE LOOP

I am also try ->

  useEffect(() => {
        let oldUsers = collectData(oldUsers);
        const filteredUsers = intersectionBy(oldUsers, valueProp, "id"); 
 
       setUsers(filteredUsers); // most important
  }, []);

Load only one and that doesn't mean anything to me..

I am try with useRef ,but that doesn't help me in this case.

I will try to explain the basis of the problem.

I need to get one get data. After that get on the click of a button, I need to merge oldUsers and users without rendering, change the state. That is problem.

If there is no solution to this problem, tell me what I could do to solve the problem?

I am googling but without succes ... I am also try this solution from interent ->

const [state, setState] = useState({});
setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

no work.

I am also try with ->

const [state, setState] = useState(() => {
  const initialState = someExpensiveComputation(props);
  return initialState;
});

Here is problem because I need to asynchronous get only after that can I looping.

Upvotes: 0

Views: 824

Answers (1)

jsejcksn
jsejcksn

Reputation: 33901

Using a ref is probably a better option for whatever it is you're ultimately trying to do.

Yes, it is possible, but it violates one of the core rules of React state: Do Not Modify State Directly.

React compares state values using Object.is equality, so if you simply mutate an object in state instead of replacing it with a new value that is not object-equal, then the state "update" will not cause a re-render (but this is considered a bug in your program!). Anyway, this is how you'd do it:

<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="env,react">

const {useCallback, useState} = React;

function Example () {
  const [state, setState] = useState([1]);

  const logState = useCallback(() => console.log(state.join(', ')), [state]);

  // Don't actually do this!!!
  const mutateState = () => {
    setState(arr => {
      arr.push(arr.at(-1) + 1);
      return arr;
    });
  };

  return (
    <>
      <div>{state.join(', ')}</div>
      <button onClick={mutateState}>Mutate state</button>
      <button onClick={logState}>Log state</button>
    </>
  );
}

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

</script>

Upvotes: 2

Related Questions