#reactjs #react-native
Вопрос:
Мне интересно, какова стандартная процедура сопоставления со значениями в состоянии в React. Карта не является частью состояния, она просто хранит ссылки на состояние для легкого доступа с помощью ключей, в этом что-то не так?
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import Constants from 'expo-constants';
import {useEffect, useState} from 'react';
export default function App() {
return (
<View style={styles.container}>
<Person personId={"Alice"} />
</View>
);
}
const Person = ({personId}) => {
const [selector, setSelector] = useState(0);
const [mom, setMom] = useState("");
const [dad, setDad] = useState("");
const parentMap = {
0: mom,
1: dad,
};
useEffect(() => {
const fetchData = async () => {
//pretend these are awaits involving personId which is
//why I can't pre-define the map values.
const _mom = "Beth";
const _dad = "Tim";
setMom(_mom);
setDad(_dad);
};
fetchData();
}, []);
return (
<View style={{alignItems: "center"}} >
<Text >
Parents name: {parentMap[selector]}
</Text>
<Button title="Toggle selector" onPress={() => setSelector(s => (s 1) % 2)} />
</View>
);
}
Ответ №1:
В этом нет ничего изначально неправильного, хотя, ИМО, это немного пахнет кодом из-за дублирования. В подобной ситуации вы можете подумать о том, чтобы сделать объект состоянием, а не иметь отдельных состояний для обоих mom
и dad
— объект также облегчит расширение компонента для добавления дополнительных значений позже (например child
, и и grandparent
т. Д.).
Вы также можете рассмотреть возможность использования массива вместо объекта, так как похоже, что ключи всегда будут числовыми указателями, начинающимися с 0.
const Person = ({ personId }) => {
const [selectedIndex, setSelectedIndex] = useState(0);
const [values, setValues] = useState(['', '']);
useEffect(() => {
setValues([_mom, _dad]);
}, []);
return (
<View style={{ alignItems: "center" }} >
<Text >
Parents name: {values[selectedIndex]}
</Text>
<Button title="Toggle selector" onPress={() => setSelectedIndex(s => (s 1) % values.length)} />
</View>
);
};
Комментарии:
1. Что, если бы вместо просто мамы и папы у меня было 100 переменных?
2. Тогда использование вместо этого только массива или объекта сделало бы управление не несколько проще, а намного проще 🙂
Ответ №2:
В этом нет ничего плохого. Вы можете вывести состояние, чтобы получить все, что вам нужно. Если это дорого с точки зрения вычислений, вы могли бы useMemo
запомнить , но это редко бывает необходимо.
Эмпирическое правило состоит в том, чтобы ваше местное состояние было как можно более нормализованным. Затем вы можете объединить/агрегировать/преобразовать его по своему усмотрению.
const [a, setA] = useState(0);
const [b, setB] = useState(0);
const hypotenuse = Math.hypot(a, b) // don't put this in the state, derive it instead
Ответ №3:
То, что вы написали, не является неправильным, но это не распространенный подход.
Улучшением было бы нечто подобное приведенному ниже.
const Person = ({personId}) => {
const [mom, setMom] = useState("");
const [dad, setDad] = useState("");
const [isMomVisible, setIsMomVisible] = useState(true);
useEffect(() => {
const fetchData = async () => {
const _mom = "Beth";
const _dad = "Tim";
setMom(_mom);
setDad(_dad);
};
fetchData();
}, []);
return (
<View style={{alignItems: "center"}} >
<Text >
Parents name: {isMomVisible ? mom : dad}
</Text>
<Button title="Toggle selector" onPress={() => setIsMomVisible(s => (!s))} />
</View>
);
}
Вот рабочая выставка