#javascript #reactjs #react-hooks
#javascript #reactjs #реагирующие хуки
Вопрос:
Я все еще новичок в React, но по мере того, как я учусь, я пытаюсь создавать повторно используемые компоненты. Я застрял в радиогруппе. У меня есть все, кроме извлечения ключа из компонента в переменную внутри моего обычного кода.
Мой компонент выглядит следующим образом:
import React, {useState, useEffect} from "react"
import {Text, TouchableOpacity, View} from "react-native"
import PropTypes from "prop-types"
import * as colors from "../defines/js_colors"
import RN_button from "./RN_button"
function RN_radioGroup(props) {
const [radioSelect, setRadioSelect] = useState("RN_button")
// useEffect(() => {}, [radioSelect])
return (
<View>
{props.radioGroupList.map((item) => {
return (
<View key={item.key}>
<RN_button
buttonText={item.label}
darkBackgroundColor={radioSelect == item.key ? colors.white : "transparent"}
darkBorderColor={colors.white}
darkTextFontColor={colors.textLightBlue}
// onPress = data => setState({ radioSelect });
onPress={() => {
setRadioSelect(item.key)
}}
/>
</View>
)
})}
</View>
)
}
RN_radioGroup.propTypes = {
radioGroupList: PropTypes.array.isRequired,
}
export default RN_radioGroup
RN_button — это пользовательский компонент кнопки, но здесь это не имеет большого значения.
radioGroupList — это массив с ключом и меткой, который я передаю в качестве реквизита, а colors содержит определения разных цветов.
function screen({navigation}) {
const [radioValue, setRadioValue] = useState("NULL")
return (
<View style={styles.container}>
<View style={styles.container}>
<RN_radioGroup radioGroupList={arrays.radioGroup1} onPress={radioValue} />
</View>
</View>
)
}
Мне нужно использовать выбранное значение ключа, которое находится в радиогруппе снаружи на экране.
Код экрана сокращен до необходимых базовых элементов, но класс radio group в точности соответствует показанному.
Спасибо за любую помощь.
Ответ №1:
Ответ практически на что угодно в react обычно один из двух:
- Не изменяйте состояние (здесь неприменимо).
- Поднимите состояние (ответ здесь).
Вам нужно сопоставить выбранное значение с общим предком компонента screen
and RN_radioGroup
— screen
кажется, что этого будет достаточно, если поместить его в состояние в компоненте.
Не [radioSelect,setRadioSelect]
используйте как часть RN_radioGroup
состояния, вместо этого передайте его как prop.
Это будет выглядеть примерно так, когда вы передаете prop of selected
RN_radioGroup
, которому будет присвоено выбранное значение.
function screen({navigation}) {
const [radioValue, setRadioValue] = useState("NULL")
return (
<View style={styles.container}>
<View style={styles.container}>
<RN_radioGroup radioGroupList={arrays.radioGroup1} selected={radioValue} onPress={setRadioValue} />
</View>
</View>
)
}
// RN_radioGroup
function RN_radioGroup(props) {
// the selected value, and the update function are now passed in as props
const { selected, onPress, radioGroupList } = props;
return (
<View>
{radioGroupList.map((item) => {
return (
<View key={item.key}>
<RN_button
buttonText={item.label}
darkBackgroundColor={radioSelect == item.key ? colors.white : "transparent"}
darkBorderColor={colors.white}
darkTextFontColor={colors.textLightBlue}
{ /* onPress, call the updater function, which I've also coincidentally named onPress */ }
onPress={() => onPress(item.key)}
/>
</View>
)
})}
</View>
)
}
Комментарии:
1. Я понимаю идею, которую вы здесь объясняете, но я понятия не имею, как ее реализовать. Я видел несколько примеров снятия состояния, они выглядят совершенно иначе в моей реализации. Всякий раз, когда я пытаюсь ее реализовать, я получаю сообщение об ошибке, в котором говорится, что я не могу «обновить компонент изнутри функционального блока другого компонента». Не могли бы вы привести мне пример того, что делать внутри класса radio group, или даже просто указать мне на хороший пример, который объясняет этот тип реализации. И спасибо вам за помощь до сих пор.
2. @HeinK кажется, я редактирую, чтобы понять, имеет ли это какой-то смысл.
Ответ №2:
Основная идея заключается в том, что вы поднимаете состояние вверх, что означает, что вы должны указать [radioSelect,setRadioSelect]
путь вверх в компоненте, который содержит RN_radioGroup
как-то так
// my screen
function screen({navigation}) {
const [radioValue, setRadioValue] = useState("NULL")
return (
<View style={styles.container}>
<View style={styles.container}>
<RN_radioGroup
radioGroupList={arrays.radioGroup1}
selected={radioValue}
onSelect={setRadioValue} />
</View>
</View>
)
}
// your RN_radioGroup
function RN_radioGroup(props) {
// you destructure the props to get these values
// you use these to change the selected value
const {selected, onSelect} = props;
return (
<View>
{props.radioGroupList.map((item) => {
return (
<View key={item.key}>
<RN_button
buttonText={item.label}
// you compare the value if it is selected here
darkBackgroundColor={selected == item.key ? colors.white : "transparent"}
darkBorderColor={colors.white}
darkTextFontColor={colors.textLightBlue}
onPress={() => {
onSelect(item.key)
}}
/>
</View>
)
})}
</View>
)
}
Комментарии:
1. Спасибо за комментарий. Адам отредактировал свой предыдущий комментарий, и вы оба посоветовали мне то же самое, но я все равно ценю ответ.