E
E
Evgeny Petrov2020-04-21 14:06:10
JavaScript
Evgeny Petrov, 2020-04-21 14:06:10

Why does ref return null objects after launching the modal?

Hello!

Help please, the second day I sit and I can not find out.
I am attaching a link to the sandbox.

The essence of the problem: there is a React application with the following structure:

--App
-----Mw (react-bootstrap modal window body)
-----MainCheckbox (main checkbox that toggles all other checkboxes)
-----CheckboxContainer ( renders checkboxes controlled by MainCheckbox)

Before App had a modal window component (Mw), checkboxes worked great. I inserted the Mw component, the modal window works, but after opening / closing the modal window, when the main checkbox is clicked, the application crashes. By debugging, I found out that the callback ref (on the basis of which the checkbox switch works), after opening / closing the modal window, returns not only all three checkboxes, but also three null-a. It feels like it saved the checkbox elements somewhere, and after re-rendering, together with the actual checkboxes, it returns the saved checkboxes, but since there are none, it returns null. I have attached the link above for reference.

Thanks in advance for any help.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
E
Evgeny Petrov, 2020-04-21
@kazsat

I figured it out , thanks to LEXA_JA for pointing out the documentation, for some reason I missed this moment. In general, ref should have been defined not as a built-in function, but to define a function as a member of the class and use it. Link

L
LEXA_JA, 2020-04-21
@LEXA_JA

Let's start with why this happens. ref fires every time a render occurs. Since the modal uses setState which calls render which runs the function in the ref, more and more references end up in the array each time the modal is opened/closed. Sometimes the ref can be null, due to the inline function More Info .
However, this approach is fundamentally wrong.
To manage the state of a checkbox, the use of ref is deprecated. The use of ref in React is basically gentle to use not very often. The correct approach is to use props: checked\defaultChecked and onChange Forms
In general, the state should be in React, and React itself applies it to the DOM, this is its essence.
The correct option is to put the state of the checkboxes in a state, in the form of an array or a Set.

state = {
    values: [false, false, false], // Изначально все 3 чекбокса выключены
  };

  onToggleCheckbox = (checked, index) => {
    this.setState(({ values: prevValues }) => {
      const newValues = [...prevValues]; // меняем состояние нужного чекбокса по индексу
      newValues[index] = checked;

      return {
        value: newValues,
      };
    });
  };

  onToggleAll = checked => {
    this.setState(({ values }) => ({
      values: values.map(() => checked),
    }));
  };

Then drawing checkboxes:
<div>
    {this.props.checked.map((value, index) => (
      <input
        type="checkbox"
        checked={value}
        key={index}
        onChange={event => this.props.onToggle(event, index)}
      />
    ))}
  </div>

Checkbox state that toggles everything else computable:
<input type="checkbox" checked={this.props.values.every(value => value)} onChange={event => this.props.onToggleAll(event.target.checked)} />

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question