Принудительное повторное рендеринг с использованием useSelector - PullRequest
1 голос
/ 17 марта 2020

Это продолжение Рефакторинг компонента класса в функциональный компонент с перехватами, получая Uncaught TypeError: fun c .apply не является функцией

Я объявил функциональный компонент Параметр, который извлекает значения из действий / редукторов, используя ловушку useSelector:

const Parameter = () => {
let viz = useSelector(state => state.fetchDashboard);
const parameterSelect = useSelector(state => state.fetchParameter)
const parameterCurrent = useSelector(state => state.currentParameter)
const dispatch = useDispatch();
const drawerOpen = useSelector(state => state.filterIconClick);

const handleParameterChange = (event, valKey, index, key) => {
    parameterCurrent[key] = event.target.value;
    return (
        prevState => ({
            ...prevState,
            parameterCurrent: parameterCurrent
        }),
        () => {
            viz
                .getWorkbook()
                .changeParameterValueAsync(key, valKey)
                .then(function () {
                    //some code describing an alert
                    });
                })

                .otherwise(function (err) {
                    alert(
                        //some code describing a different alert
                    );
                });
        }
    );
};
const classes = useStyles();
return (
    <div>
        {drawerOpen ? (
            Object.keys(parameterSelect).map((key, index) => {
                return (
                    <div>
                        <FormControl component="fieldset">
                            <FormLabel className={classes.label} component="legend">
                                {key}
                            </FormLabel>
                            {parameterSelect[key].map((valKey, valIndex) => {
                                return (
                                    <RadioGroup
                                        aria-label="parameter"
                                        name="parameter"
                                        value={parameterCurrent[key]}//This is where the change should be reflected in the radio button
                                        onChange={(e) => dispatch(
                                            handleParameterChange(e, valKey, index, key)
                                        )}
                                    >
                                        <FormControlLabel
                                            className={classes.formControlparams}
                                            value={valKey}
                                            control={
                                                <Radio
                                                    icon={
                                                        <RadioButtonUncheckedIcon fontSize="small" />
                                                    }
                                                    className={clsx(
                                                        classes.icon,
                                                        classes.checkedIcon
                                                    )}
                                                />
                                            }
                                            label={valKey}
                                        />
                                    </RadioGroup>
                                );
                            })}
                        </FormControl>
                        <Divider className={classes.divider} />
                    </div>
                );
            })
        ) : (
                <div />
            )
        }
    </div >
)
};
export default Parameter;

Мне нужно, чтобы значение = {parameterCurrent [key]} повторно отображалось на handleParameterChange (handleChange обновляет данные базовой панели, но переключатель не отображается как выбранный, пока я не закрою основной компонент и не открою его снова). Я думал, что у меня есть решение, в котором я принудительно сделал повторное рендеринг, но, поскольку это меньший компонент, который является частью большего, он ломал другие части компонента (то есть он выполнял повторный рендеринг и предотвращал получение другого компонента). состояние / реквизит от это редукторы). Я был на inte rnet в поисках решений в течение 2 дней и пока не нашел ничего, что работает. Любая помощь очень ценится! ТИА!

Ответы [ 2 ]

1 голос
/ 17 марта 2020

useSelector() использует строгие === проверки равенства ссылок по умолчанию, а не неглубокое равенство.

Чтобы использовать неглубокие проверки равенства, используйте эту

import { shallowEqual, useSelector } from 'react-redux'

const selectedData = useSelector(selectorReturningObject, shallowEqual)

Подробнее

0 голосов
/ 17 марта 2020

Хорошо, после многих итераций я нашел способ заставить его работать (я уверен, что это не самый красивый или самый эффективный, но он работает, поэтому я продолжу с ним). Я разместил код с изменениями ниже.

Я добавил строки updateState и forceUpdate при объявлении общей функции Parameter:

const Parameter = () => {
let viz = useSelector(state => state.fetchDashboard);
const parameterSelect = useSelector(state => state.fetchParameter)
const parameterCurrent = useSelector(state => state.currentParameter);
const [, updateState] = useState();
const forceUpdate = useCallback(() => updateState({}), []);
const dispatch = useDispatch();
const drawerOpen = useSelector(state => state.filterIconClick);

Затем добавил строку forceUpdate () здесь:

const handleParameterChange = (event, valKey, index, key) => {
parameterCurrent[key] = event.target.value;
return (
    prevState => ({
        ...prevState,
        parameterCurrent: parameterCurrent
    }),
    () => {
        viz
            .getWorkbook()
            .changeParameterValueAsync(key, valKey)
            .then(function () {
                //some code describing an alert
                });
            })

            .otherwise(function (err) {
                alert(
                    //some code describing a different alert
                );
            });
forceUpdate() //added here
    }
);

};

Затем вызвал forceUpdate в операторе возврата для элемента, который я хотел повторно визуализировать:

<RadioGroup
                                        aria-label="parameter"
                                        name="parameter"
                                        value={forceUpdate, parameterCurrent[key]}//added forceUpdate here
                                        onChange={(e) => dispatch(
                                            handleParameterChange(e, valKey, index, key)
                                        )}
                                    >

Я проверил это, и он не нарушает никакой другой код. Спасибо!

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