Реагировать не на рендеринг, когда состояние ловушки useState меняется (Object.is = false) - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть функциональный компонент React с использованием хуков. Компонент основан на двух дочерних элементах:

  1. Первый - это таблица, в которой перечислены данные (временные ряды), в которых можно выбрать строки.
  2. Диаграмма, на которой я собираюсь построить диаграмму выделенные строки таблицы выше.

Проблема, с которой я сталкиваюсь, заключается в том, что при выборе новых строк часть диаграммы обновляется. Но это не так, когда я отменяю выбор строк.

Компоненты для рендеринга выглядят следующим образом:

const chart = (isChartLoading ? <div>Loading ...</div> :
    <TSChart
        initialRange={initialRange}
        channels={channels}
        style={style}
    />);

return (
    <div> {
        error ? (<div className="App-error"><p>{error}</p></div>) :
            (<div style={{maxWidth: '100%'}}>
                <TSTable
                    tsList={tsList}
                    onSelectTableRow={onSelectTableRow}
                />
            </div>)}
        {chart}
    </div>
)

И вот те хуки, которые я использую:

const [tsList, setTsList] = useState([]);
const [channels, setChannels] = useState({});
const [isChartLoading, setIsChartLoading] = useState(false);

const [error, setError] = useState(null);

useEffect(() => {
    function fetchTsList() {
        axios.get(urlList)
            .then(result => setTsList(result.data))
            .catch(() => setError('Impossible to get TS list'));
    }

    fetchTsList()
}, []);

Выбор строки управления кодом следующий:

function onSelectTableRow(rows) {
    const currentChannelsNames = Object.keys(channels);
    const selectedChannelsNames = rows.map(row => row.name);

    // Remove deselected channels from charted channels
    const deselectedChannelsNames = currentChannelsNames.filter(x => !selectedChannelsNames.includes(x));

    function removeDeselectedChannels(channels) {
        const updatedChannels = {...channels};
        deselectedChannelsNames.forEach((name) => {
            delete updatedChannels[name];
            removeGraphStyleArray(name);
        });
        style = styler(style_array);
        console.log('channels in removeDeselectedChannels', channels);
        console.log('updatedChannels in removeDeselectedChannels', updatedChannels);
        console.log(Object.is(channels, updatedChannels));
        return updatedChannels;
    }
    if (deselectedChannelsNames.length !== 0) setChannels(removeDeselectedChannels);

    // Manage additional channels
    const newChannelsNames = selectedChannelsNames.filter(x => !currentChannelsNames.includes(x));
    // Load the additional channel(s)
    if (newChannelsNames.length !== 0) newChannelsNames.forEach(fetchTSValues);
}

Как видите, я использую трассировки (console.log) для трассировки изменения состояния channels. Когда я отменяю выбор строки, состояние channels действительно меняется, как показано на следующих трассах:

channels in removeDeselectedChannels {demo-temperature-4: {…}}
updatedChannels in removeDeselectedChannels {}
false

И Object.is действительно говорит, что channels обновленное состояние отличается от предыдущего состояния. Тем не менее, компонент TSChart не перерисовывается, оставаясь с отображением ранее выбранного временного ряда.

Есть какие-то подсказки, чего мне не хватает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...