Javascript 从子级访问useState钩子
现在,每个子项(SelectorButton)都可以打开和关闭,如果打开,则该组件的标题将添加到父页面上的“当前”数组中,当关闭时,该组件的标题将从数组中弹出。我试图将其设置为,如果“当前”数组中有多个标题(至少按下一个按钮),则“下一步”按钮可见 我现在遇到的问题是,控制按钮内容的if语句总是认为'current.length'==0,这是因为它没有重新加载,它在第一次加载页面时查看的是'current'的初始状态 我非常确定我需要将“当前”设置为useState钩子,但不知道如何将该信息传递到每个组件中,以便更新它。很抱歉,如果这个解释有点难理解,我很乐意回答任何问题。非常感谢您的帮助:) 父页面:Javascript 从子级访问useState钩子,javascript,reactjs,react-native,Javascript,Reactjs,React Native,现在,每个子项(SelectorButton)都可以打开和关闭,如果打开,则该组件的标题将添加到父页面上的“当前”数组中,当关闭时,该组件的标题将从数组中弹出。我试图将其设置为,如果“当前”数组中有多个标题(至少按下一个按钮),则“下一步”按钮可见 我现在遇到的问题是,控制按钮内容的if语句总是认为'current.length'==0,这是因为它没有重新加载,它在第一次加载页面时查看的是'current'的初始状态 我非常确定我需要将“当前”设置为useState钩子,但不知道如何将该信息传递
...
import SelectorButton from '../components/selectorButton';
const SignUpOne = ({ navigation }) => {
//this gets updated as they click or click off a button
//this hold the current pressed buttons
//pretty sure this needs to be a state but Im not sure how to
//pass this into children
let current = []
let nextButton
if (current.length >= 1) {
//next button is visible
console.log('is visible')
nextButton = <TouchableOpacity><Text>Next</Text></TouchableOpacity>
} else {
//its not visisble
console.log('not visible')
nextButton = <View></View>
}
const textFunction = () => {
console.log(current)
}
return (
<View style={styles.screen}>
<ScrollView bounces={false}>
<View style={{ margin: 20, flex: 1 }}>
{/*back button */}
<View style={{ width: '100%', flexDirection: 'row', justifyContent: 'space-between' }}>
<TouchableOpacity onPress={textFunction} style={styles.backButton}>
<Text>back</Text>
</TouchableOpacity>
<View style={styles.backButton}>
<Text>hi</Text>
</View>
</View>
<View style={styles.stepNotify}>
<Text style={styles.stepText}>Step 1 of 3</Text>
</View>
<Text style={styles.question}>What are you looking to improve?</Text>
{/*this is where the actual buttons are*/}
<View style={styles.optionContainer}>
{/*top row of buttons */}
<View style={{
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
}}>
{/*actual button item */}
<SelectorButton array={current} title='Health'>
<Text>icon</Text>
</SelectorButton>
<SelectorButton array={current} title='???'>
<Text>icon</Text>
</SelectorButton>
</View>
{/*middle row of buttons */}
<View style={styles.rowContainer}>
{/*actual button item */}
<SelectorButton array={current} title='Relationships'>
<Text>icon</Text>
</SelectorButton>
<SelectorButton array={current} title='Time Allocation'>
<Text>icon</Text>
</SelectorButton>
</View>
{/*final row of buttons */}
<View style={styles.rowContainer}>
{/*actual button item */}
<SelectorButton array={current} title='Career'>
<Text>icon</Text>
</SelectorButton>
<SelectorButton array={current} title='Mental Health'>
<Text>icon</Text>
</SelectorButton>
</View>
</View>
</View>
</ScrollView>
</View >
)
}
export default SignUpOne
...
。。。
从“../components/SelectorButton”导入SelectorButton;
const SignUpOne=({navigation})=>{
//当他们单击或单击某个按钮时,会对其进行更新
//这将保持当前按下的按钮
//相当肯定这需要一个状态,但我不知道如何
//把这个传给孩子们
让电流=[]
让我们下一个按钮
如果(当前长度>=1){
//“下一步”按钮可见
console.log('可见')
下一个按钮=下一个
}否则{
//这是不可访问的
console.log('不可见')
下一个按钮=
}
常量文本函数=()=>{
console.log(当前)
}
返回(
{/*后退按钮*/}
返回
你好
第1步,共3步
你希望改进什么?
{/*这是实际按钮所在的位置*/}
{/*按钮的顶行*/}
{/*实际按钮项*/}
偶像
偶像
{/*中间一行按钮*/}
{/*实际按钮项*/}
偶像
偶像
{/*最后一行按钮*/}
{/*实际按钮项*/}
偶像
偶像
)
}
导出默认SignUpOne
...
SelectorButton组件:
...
const SelectorButton = (props) => {
//remember that it is rendered for each button seperatley
//when active is == true, we want it to be added to an array,
//if it is updated to false, we want to remove it from the array,
//on submit, we want to push the remaining items to the user profile
const [active, updateActive] = useState(false)
//this has the
const updateActiveHandler = () => {
updateActive(prev => !prev)
if (active == true) {
console.log(props.title, 'is off')
let index = props.array.indexOf(props.title)
props.array.splice(index, 1)
} else {
console.log(props.title, 'is on')
props.array.push(props.title)
}
}
return (
<View {...props} >
{!active &&
<View style={{ alignItems: 'center' }}>
<TouchableOpacity activeOpacity={1} onPress={updateActiveHandler} style={styles.selectionButton}>
{props.children}
</TouchableOpacity>
<Text style={styles.selectionButtonLabel}>{props.title}</Text>
</View>
}
{active &&
<View style={{ alignItems: 'center' }}>
<TouchableOpacity activeOpacity={1} onPress={updateActiveHandler} style={styles.pressedSelectionButton}>
{props.children}
</TouchableOpacity>
<Text style={styles.pressedSelectionLabel}>{props.title}</Text>
</View>
}
</View>
)
}
export default SelectorButton;
...
。。。
常量选择器按钮=(道具)=>{
//请记住,它是为每个按钮单独渲染的
//当active为==true时,我们希望将其添加到数组中,
//如果更新为false,我们希望将其从数组中删除,
//提交时,我们希望将剩余的项目推送到用户配置文件中
常量[active,updateActive]=useState(false)
//这有
const updateActiveHandler=()=>{
updateActive(prev=>!prev)
如果(活动==真){
console.log(props.title“已关闭”)
让index=props.array.indexOf(props.title)
道具阵列拼接(索引,1)
}否则{
console.log(props.title'is on')
道具.数组.推送(道具.标题)
}
}
返回(
{!激活&&
{props.children}
{props.title}
}
{活动的&&
{props.children}
{props.title}
}
)
}
导出默认选择器按钮;
...
对于更多的上下文,这里是正在呈现的页面,SelectorButton是每个或多个框,当至少按下一个按钮(变为蓝色)时,next按钮显示)还需要确保所有按下的按钮都已存储(在下一个注册步骤中添加到firebase用户配置文件)
是的
const [current, setCurrent] = useState([])
就我所知,这是正确的解决办法。然后简单地将setCurrent函数作为道具传递给必要的子级。之后,您将能够更新子组件的当前值。就像一些答案已经告诉您的那样,您可以传递setState,实际上您可以传递任何内容 当您有
const[current,setCurrent]=useState(“”)时代码>然后您可以传递current和setCurrent
另一件事是,当您不需要状态,但希望有一个类似于类属性的变量时,最好使用“useRef”:
由let创建的普通变量的问题是,例如,您有一个变量“current”,它用一个空数组初始化,当您将其更改为其他变量,然后当您的组件重新加载时(因为状态已更改),则current将再次用空数组初始化
您可以认为,当您的组件重新渲染时,就像react第一次渲染您的组件一样,唯一的区别是,您的状态现在与第一次渲染时不同。另外:props.array.pus
const whatever = useRef("");
whatever.current = "new value";
console.log(whatever.current) // new value