Рефакторинг компонента класса в функциональный компонент с перехватами, получая Uncaught TypeError: fun c .apply не является функцией - PullRequest
0 голосов
/ 14 марта 2020

Это моя первая попытка рефакторинга кода из компонента класса в функциональный компонент с использованием перехватчиков React. Причина, по которой мы проводим рефакторинг, заключается в том, что в настоящее время компонент использует метод lifecylcle, который скоро станет недействительным, и мы не смогли заставить другие методы жизненного цикла работать так, как нам хочется. Для фона исходный компонент имел вышеупомянутый метод жизненного цикла cWRP, функцию handleChange, использовал connect и mapStateToProps и связывается с хранилищем панелей мониторинга таблиц через API таблиц. Я также разбиваю компонент, который имел четыре отличительные особенности, на их собственные компоненты. Код, с которым у меня возникают проблемы, таков:

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

useEffect(() => {
    let keys1 = Object.keys(parameterCurrent);
    if (
        keys1.length > 0 //if parameters are available for a dashboard
    ) {
        return ({
            parameterSelections: parameterCurrent
        });
    }
}, [props.parameterCurrent])

const handleParameterChange = (event, valKey, index, key) => {
    parameterCurrent[key] = event.target.value;
    console.log(parameterCurrent[key]);
    return (
        prevState => ({
            ...prevState,
            parameterSelections: parameterCurrent
        }),
        () => {
            viz
                .getWorkbook()
                .changeParameterValueAsync(key, valKey)
                .then(function () {
                    Swal.fire({
                        position: "center",
                        icon: "success",
                        title:
                            JSON.stringify(key) + " set to " + JSON.stringify(valKey),
                        font: "1em",
                        showConfirmButton: false,
                        timer: 2500,
                        heightAuto: false,
                        height: "20px"
                    });
                })

                .otherwise(function (err) {
                    alert(
                        Swal.fire({
                            position: "top-end",
                            icon: "error",
                            title: err,
                            showConfirmButton: false,
                            timer: 1500,
                            width: "16rem",
                            height: "5rem"
                        })
                    );
                });
        }
    );
};
const classes = useStyles();
return (
    <div>
        {Object.keys(parameterSelect).map((key, index) => {
            return (
                <div>
                    <FormControl component="fieldset">
                        <FormLabel className={classes.label} component="legend">
                            {key}
                        </FormLabel>
                        {parameterSelect[key].map((valKey, valIndex) => {
                            console.log(parameterSelections[key])
                            return (
                                <RadioGroup
                                    aria-label="parameter"
                                    name="parameter"
                                    value={parameterSelections[key]}
                                    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 >
)}; 
export default Parameter;

Классы const определяются отдельно и все импорты редукторов и т. Д. c. были завершены. Параметр parameterSelect в коде указывает на все доступные параметры, в то время как параметр parameterCurrent указывает на параметры по умолчанию, выбранные на информационной панели (т. е. с чем изначально загружается визу).

Происходят две вещи: 1. При начальной визуализации все загружается нормально, и когда я нажимаю переключатель, чтобы изменить параметр, я вижу его обновление на панели инструментов - однако на самом деле радио не отображается. кнопка как выбранная (она все еще показывает какой параметр viz инициализирован как выбранный). 2. Когда я щелкаю за пределами панели фильтров (куда импортируется этот компонент), я получаю Uncaught TypeError: fun c .apply не является функцией. Я произвел рефакторинг другого компонента, и у меня не было этой проблемы, и я не могу определить, правильно ли я закодировал в хуке useEffect, функции handleParameterChange или где-то в операторе return. Любая помощь очень ценится этим новичком ie !!!

1 Ответ

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

Это большой код, который нужно взять, не видя исходного класса или не имея песочницы для загрузки кода. Вначале я думал, что это может быть ваш useEffect

. В вашем рефакторированном коде вы говорите своему useEffect перезапускаться только при изменении props.parameterCurrent. Однако внутри useEffect вы не используете props.parameterCurrent, вместо этого вы используете parameterCurrent из локальной лексической области. Общее практическое правило: любые значения, используемые в вычислениях внутри useEffect, должны быть в списке повторных зависимостей.

useEffect(() => {
    let keys1 = Object.keys(parameterCurrent);
    if (
        keys1.length > 0 //if parameters are available for a dashboard
    ) {
        return ({
            parameterSelections: parameterCurrent
        });
    }
}, [parameterCurrent])

Однако этот useEffect, похоже, ничего не делает, поэтому, хотя его список зависимостей неверен, я не думаю, что он решит проблему, которую вы описываете.

Я бы посмотрел на вашу рассылку и селектор. Дважды проверьте, что хранилище с избыточностью обновляется, как ожидается, и что новое значение переносит его из обратного вызова изменения в хранилище и обратно, не теряя его из-за неправильного вложения, неправильных имен ключей и т. Д. c .. .

Я бы рекомендовал опубликовать ссылку CodeSandbox.io или исходный класс для дальнейшей помощи в отладке.

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