Итак, у меня есть приведенный ниже код, который я хотел бы реорганизовать, поэтому мне не придется повторять его снова и снова. Я сделал функцию saveQuestion, но она решает половину проблемы. Мне не нужно звонить setDeleteFilters(true); setFiltersAreApplied(true); снова ... Но есть ли способ вызывать функцию saveQuestion каждый раз с другим хуком, как один раз с setAlfaIsTrue(newValue);, затем с setBetaIsTrue(newValue); и т. Д.? Основная проблема, я думаю, это зависимости ...

Спасибо :)

const saveQuestion = useCallback(
        () => {
            setDeleteFilters(true);
            setFiltersAreApplied(true);
        },
        [ deleteFilters, filtersAreApplied ]
    );

    const saveAlfa = useCallback(
        (newValue) => {
            setAlfaIsTrue(newValue);
            saveQuestion();
            // setDeleteFilters(true);
            // setFiltersAreApplied(true);
        },
        [ alfaIsTrue ]
    );
    const saveBeta = useCallback(
        (newValue) => {
            setBetaIsTrue(newValue);
            saveQuestion();
            // setDeleteFilters(true);
            // setFiltersAreApplied(true);
        },
        [ betaIsTrue ]
    );

Я получил именно то, что хотел от T.J.Crowder и вот как выглядит код сейчас. Красиво и лаконично.

const [ saveAlfa, saveBeta, saveGamma, saveDelta ] = [
        setAlfaIsTrue,
        setBetaIsTrue,
        setGammaIsTrue,
        setDeltaIsTrue
    ].map((fn, flag) =>
        useCallback((newValue) => {
            fn(newValue);
            setDeleteFilters(true);
            setFiltersAreApplied(true);
        }, [flag])
    );

Спасибо +++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++

Вот весь код: мне все еще нужно исправить зависимости ...


const AnswerSwitch = (props) => {
    return (
        <View style={styles.multipleChoiceContainer}>
            {/* <Text style={{color:Colours.moccasin_light}} >{props.label}</Text> */}
            <BoldText>{props.label}</BoldText>
            <View style={{ marginHorizontal: 10 }}>
                <Switch
                    style={{ transform: [ { scaleX: 1 }, { scaleY: 0.7 } ] }}
                    thumbColor={Platform.OS === 'android' ? Colours.maroon : ''}
                    trackColor={Platform.OS === 'android' ? Colours.moccasin_light : ''}
                    value={props.state}
                    onValueChange={props.onChange}
                    disabled={props.disabled}
                />
            </View>
        </View>
    );
};

////////////////////////////////////////////////////////
const DifficultyLevelSettingsScreen = (props) => {
    const { width, height } = Dimensions.get('window');
    const widthMultiplier = DimensionsForStyle.widthMultiplier;
    const textMultiplier = DimensionsForStyle.textMultiplier;
    const cardHeight = DimensionsForStyle.cardHeight;
    const cardWidth = DimensionsForStyle.cardWidth;

    const dispatch = useDispatch();
    const [ isLoading, setIsLoading ] = useState(false);

    // For the switches
    // They run when a switch is touched
    const [ alfaIsTrue, setAlfaIsTrue ] = useState(true);
    const [ betaIsTrue, setBetaIsTrue ] = useState(true);
    const [ gammaIsTrue, setGammaIsTrue ] = useState(true);
    const [ deltaIsTrue, setDeltaIsTrue ] = useState(true);

    // For checking if we have filters on the server so we set their state from there...
    const [ filtersAreApplied, setFiltersAreApplied ] = useState(false);

    // Gets updated everytime we set a filter, so we delete their previous state
    const [ deleteFilters, setDeleteFilters ] = useState(false);

    // Get state of filters from redux to update them
    // const savedFilters = useSelector((state) => state.questions.filters);

    const loadFilters = useCallback(
        async () => {
            const userFilters = await AsyncStorage.getItem('userFilters');
            const savedFilters = JSON.parse(userFilters);

            let applySavedFilters = false;
            for (const key in savedFilters) {
                applySavedFilters = savedFilters[key].filtersAreApplied;
                // If we have savedFilters and we didn't press a switch then...

                if (applySavedFilters && !deleteFilters) {
                    setAlfaIsTrue(savedFilters[key].alfa);
                    setBetaIsTrue(savedFilters[key].beta);
                    setGammaIsTrue(savedFilters[key].gamma);
                    setDeltaIsTrue(savedFilters[key].delta);
                    // setFiltersAreApplied(false)
                }
            }

            // Get state of filters to send them to server
            const appliedFilters = {
                alfa: alfaIsTrue,
                beta: betaIsTrue,
                gamma: gammaIsTrue,
                delta: deltaIsTrue,
                filtersAreApplied: filtersAreApplied
            };
            // If a switch is touched then 'deleteFilters' will be true.
            if (deleteFilters || savedFilters.filtersAreApplied) {
                await dispatch(questionsActions.deletePreviousFilters());
                await dispatch(questionsActions.setFilters(appliedFilters));
            }

            // Fetch them again to update the "initial" state of filters...
            // dispatch(questionsActions.fetchFilters());
        },
        [ alfaIsTrue, betaIsTrue, gammaIsTrue, deltaIsTrue, deleteFilters, filtersAreApplied, dispatch ]
    );

    // loadFilters after focusing
    useEffect(
        () => {
            const willFocusEvent = props.navigation.addListener('willFocus', loadFilters);
            return () => willFocusEvent.remove();
        },
        [ loadFilters ]
    );

    // loadFilters initially...
    useEffect(
        () => {
            setIsLoading(true);
            loadFilters().then(() => setIsLoading(false));
        },
        [ loadFilters ]
    );

    // For setting the email on the HeaderTitle
    useEffect(
        () => {
            const getData = async () => {
                // Note: getItem is asynchronous, so we get a promise
                await dispatch(questionsActions.fetchAllUsersData());
                const userData = await AsyncStorage.getItem('userData');
                if (userData) {
                    // parse converts a string to an object or array
                    const transformedData = JSON.parse(userData);
                    const { userEmail } = transformedData;
                    props.navigation.setParams({ userEmail: userEmail });
                }
            };
            getData();
        },
        [ dispatch ]
    );

    const saveQuestion = useCallback(
        () => {
            // So filters on server will not be deleted
            // when you open the DifficultyLevelSettingsScreen, unless you make a change.
            setDeleteFilters(true);
            setFiltersAreApplied(true);
        },
        [ deleteFilters, filtersAreApplied ]
    );

    // These actions run when the according switch is touched...
    const saveAlfa = useCallback(
        (newValue) => {
            setAlfaIsTrue(newValue);
            saveQuestion()
        },
        [ alfaIsTrue ]
    );
    const saveBeta = useCallback(
        (newValue) => {
            setBetaIsTrue(newValue);
            saveQuestion()
        },
        [ betaIsTrue ]
    );
    const saveGamma = useCallback(
        (newValue) => {
            setGammaIsTrue(newValue);
            saveQuestion()
        },
        [ gammaIsTrue ]
    );
    const saveDelta = useCallback(
        (newValue) => {
            setDeltaIsTrue(newValue);
            saveQuestion()
        },
        [ deltaIsTrue ]
    );

    return (
        // <CustomLinearGradient>
        <ScrollView style={styles.screen}>
            <View style={styles.difficultyLevelStyle}>
                {isLoading ? (
                    <ActivityIndicator size="small" color={Colours.maroon} />
                ) : (
                    <BoldText style={styles.title}>Επιλογή βαθμού (ή βαθμών) δυσκολίας</BoldText>
                )}

                <View style={styles.switchesSummary}>
                    <AnswerSwitch
                        state={alfaIsTrue}
                        // onChange={(newValue) => setAlfaIsTrue(newValue)}
                        onChange={saveAlfa}
                        label="Επίπεδο: Α"
                        // disabled={betaIsTrue || gammaIsTrue || deltaIsTrue}
                    />
                    <AnswerSwitch
                        state={betaIsTrue}
                        // onChange={(newValue) => setBetaIsTrue(newValue)}
                        onChange={saveBeta}
                        label="Επίπεδο: Β"
                        // disabled={alfaIsTrue || gammaIsTrue || deltaIsTrue}
                    />
                    <AnswerSwitch
                        state={gammaIsTrue}
                        // onChange={(newValue) => setGammaIsTrue(newValue)}
                        onChange={saveGamma}
                        label="Επίπεδο: Γ"
                        // disabled={alfaIsTrue || betaIsTrue || deltaIsTrue}
                    />
                    <AnswerSwitch
                        state={deltaIsTrue}
                        // onChange={(newValue) => setDeltaIsTrue(newValue)}
                        onChange={saveDelta}
                        label="Επίπεδο: Δ"
                        // disabled={alfaIsTrue || betaIsTrue || gammaIsTrue}
                    />
                    <Line />
                </View>
            </View>
        </ScrollView>
        // </CustomLinearGradient>
    );
};

DifficultyLevelSettingsScreen.navigationOptions = ({ navigation }) => {
    return {
        headerTitle: navigation.getParam('userEmail'),
        headerLeft: (
            <HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
                <Item
                    title="menu"
                    iconName={Platform.OS === 'android' ? 'md-menu' : 'ios-menu'}
                    onPress={() => navigation.toggleDrawer()}
                />
            </HeaderButtons>
        )

    };
};

Есть также другой файл с 10 переключателями ...

0
Fotios Tsakiris 18 Дек 2019 в 13:48

1 ответ

Лучший ответ

Этот пользовательский хук сделает свое дело

const useSaveQuestion = (saveFunc, deps) =>
    useCallback(
        newValue => {
            saveFunc(newValue);
            setDeleteFilters(true);
            setFiltersAreApplied(true);
        },
        [deleteFilters, filtersAreApplied, ...deps],
    );

И вот как вы используете это:

const saveAlfa = useSaveQuestion(
    newValue => {
        setAlfaIsTrue(newValue);
        saveQuestion();
    },
    [alfaIsTrue],
);

const saveBeta = useSaveQuestion(
    newValue => {
        setBetaIsTrue(newValue);
        saveQuestion();
    },
    [betaIsTrue],
);
1
Thierry Prost 18 Дек 2019 в 11:21