React Native 0.63.2应用程序中有一个父函数组件Itie
和一个子组件MyAccordion
。想法是在将图片上传到父级Itie
中之后,然后应打开子级MyAccordion
来显示图片。这是父级Itie
中的相关代码:
import MyAccordion from "../app/MyAccordion"; //<<==import child component
export default function Itie({navigation}) {
const [accordImgOpen, setImgAccordOpen] = useState(false); //<<==define state accorImgOpen
const addImages = (pics) => {
if (!pics || pics===[] || pics==={}) return;
setImgAccordOpen(true); //update accorImgOpen to true in images upload
//do something...
};
const updateImgAccord = (status) => { //<<==allow update from MyAccordion
setImgAccordOpen(status);
};
return (
<MyAccordion
title={"Image"}
absPosition={false}
initOpen={accordImgOpen} //<<==pass accordImgOpen to child MyAccordion
screenSize={{width:screen_width, height:((imgs && imgs.length>9) ? screen_width+(screen_width/3)*(Math.ceil(((imgs.length-9)%3)/3)):screen_width)}}
updateStatus={updateImgAccord} //<<==pass method to MyAccordion
>
<DisplayImages pics={imgs} deleteImage={deleteImage} updateImage={(new_img)=> {setImgs(new_img)}} swipeImage={(indx) => swipeImage(indx)}/> //<<==display images in child MyAccordion
</MyAccordion>
);
在子项MyComponent
中,状态open
被定义为控制手风琴的打开/关闭:
function MyAccordion({ title, children, updateStatus, initOpen, absPosition=true, screenSize=null }) { //
const [open, setOpen] = useState(initOpen); //<<==initial value of open is from parent
const toggleListItem = () => { //<<==open/close accordion by state open
console.log("Accordion status : ", open);
if (open) {
Animated.timing(animatedController, {
duration: 300,
toValue: 1,
easing: Easing.bezier(0.4, 0.0, 0.2, 1),
useNativeDriver:false,
}).start();
} else {
Animated.timing(animatedController, {
duration: 300,
toValue: 0,
easing: Easing.bezier(0.4, 0.0, 0.2, 1),
useNativeDriver:false,
}).start();
}
setOpen(!open); //update state open
updateStatus(!open); //update parent state (accordImgOpen)
};
return (
<>
<TouchableWithoutFeedback onPress={() => toggleListItem()}> //<<==toggleListItem is called with user click
<View style={styles.titleContainer}>
<Text>{title}</Text>
<Animated.View style={{ transform: [{ rotateZ: arrowAngle }] }}>
<Icon name="chevron-down-outline" size={20} />
</Animated.View>
</View>
</TouchableWithoutFeedback>
<Animated.View style={[styles.bodyBackground, { height: bodyHeight }]}>
<View
style={[(absPosition ? styles.bodyContainerAbs : styles.bodyContainerCenter), (screenSize ? {width:screenSize.width, height:screenSize.height} : null)]}
onLayout={event => {
if (screenSize) {
setBodySectionHeight(screenSize.height);
} else {
setBodySectionHeight(event.nativeEvent.layout.height);
};
console.log("layout : ", event.nativeEvent.layout);
}
}>
{children}
</View>
</Animated.View>
</>
);
};
问题在于,当父MyAccordion
中上载的图像和Itie
中的状态open
未相应更新时,子MyAccordion
不会重新渲染。这里缺少什么?我是否应将状态open
放入子return
的{{1}}中以强制重新渲染?