React Native中仅渲染子组件而非父组件的实现问题
解决方案:下拉选项变更时仅重渲染子组件
我来帮你解决这个问题,咱们一步步分析和修改代码:
先看原代码的核心问题
- CrewsAdapter里的
crewName是普通变量:修改普通变量不会触发组件重渲染,所以永远接收到的是初始值,根本不会更新 - Crew组件没必要维护内部状态:你用了
componentWillReceiveProps同步状态,但这个生命周期已经过时,而且完全没必要——直接用props就够了 - CrewsScreen动态创建组件:在
render里包装GraphQL组件会导致每次父组件渲染都生成新组件,引发不必要的重渲染
第一步:修复CrewsScreen的组件定义错误
把GraphQL包装的组件移到CrewsScreen类外面,避免每次渲染都生成全新组件:
// 把这行移到CrewsScreen类的外部! const AllCrews = graphql(crewsList, {options: (props => ({}))})(CrewsAdapter); export default class CrewsScreen extends Component { constructor(props) { super(props); // 如果你不需要父组件维护crewName状态,直接删掉下面两行 // this.stateHandler = this.stateHandler.bind(this); // this.state = { crewName: '', } } // 不需要父组件处理状态的话,直接删除这个方法 // stateHandler(value){ // this.setState({crewName: value}); // console.log('crewName: ' + this.state.crewName); // } render() { return ( <SafeAreaView style={styles.screen}> <ToolBar /> {/* 不需要传递stateHandler了,让CrewsAdapter自己管理状态 */} <AllCrews /> <CrewsListFooter navProps={{...this.props}}/> </SafeAreaView> ); } }
第二步:让CrewsAdapter用本地状态管理选中值
把crewName改成组件状态,这样下拉选项变更时会触发CrewsAdapter局部重渲染(不会影响父组件),同时把最新值传给
import { useState } from 'react'; // 用React.memo包裹,避免props没变化时的不必要重渲染 const CrewsAdapter = React.memo(props => { // 初始化选中值为默认的'jack nickelson' const [crewName, setCrewName] = useState('jack nickelson'); if(props.data.loading) { return <View><Text>Loading crews</Text></View> } if(props.data.getAllCrews) { const crewsNames= props.data.getAllCrews.map(crew => ({"value": crew.crewName})); return ( <View style={{ flexDirection: 'column', alignItems: 'center', backgroundColor: '#ffffff' }}> <View style={[styles.container, { flex: 0.25 }]}> <Text style={styles.headerText}>Crews</Text> </View> <View style={{ flexDirection: 'row' }}> <View style={{ flex: 0.9 }}> {/* 下拉选项变更时更新本地状态 */} <Dropdown label="Crews List" data={crewsNames} onChangeText={(value) => setCrewName(value)} /> </View> </View> <View style={{ flexDirection: 'row' }}> {/* 把最新选中的crewName传给子组件 */} <Crew crewName={crewName}/> </View> </View> ); } return <View><Text>No data</Text></View> });
第三步:简化Crew组件,直接用props
删掉内部状态和过时的生命周期,直接使用传入的props,这样props变化时组件会自动更新:
// 改成函数组件更简洁,类组件也可以去掉内部状态 export default function Crew(props) { return ( <View> {/* 直接使用props里的crewName即可 */} <Text>Selected Crew: {props.crewName}</Text> {/* 这里写你的Crew组件其他内容 */} </View> ); } // 如果坚持用类组件: // export default class Crew extends Component { // render() { // return ( // <View> // <Text>Selected Crew: {this.props.crewName}</Text> // </View> // ); // } // }
这样修改后,下拉选项变更时只会触发CrewsAdapter和
内容的提问来源于stack exchange,提问作者F. K.
相关产品推荐
相关产品推荐

