在项目开发的过程中,遇到了一个问题:
父组件请求后台数据,收到后将数据以props传给子组件,子组件根据收到数据的不同,显示不同的内容,同时,子组件自身可以根据click操作改变根据父组件的数据显示的内容。
因此,子组件收到父组件的props传值后,由于props值不能修改,因此子组件需要将该props值放入state,子组件根据自身click操作改变state,进而改变组件显示的内容。
而父组件传过来的值,子组件在componentDidMount中无法获取,可以在render中获取。但是若将获取值的部分写在render中,会导致页面每次更新都从父组件拿值,子组件的click操作修改值无法起作用。
子组件代码如下:
class child extends PureComponent { static propTypes = { value: PropTypes.bool.isRequired }; constructor(props) { super( props); this.state = { value: false }; } changeValue = () => { this.setState({ value: false }); } render() { this.state = { value: this.props.value }; return ( <div style={{ display: value ? 'block':'none' }}> <img src={src} alt="" /> <div className={styles.value}>这是父组件的传值:{value}</div> <div className={styles['icon-close']} onClick={this.changeValue}> <img src={close} alt="" /> </div> </div> ); } } export default Child;
解决方法1:将click的close方法写在render中
但该写法不是很规范,render() 函数应该是纯粹的,也就是说该函数不修改组件state,每次调用都返回相同的结果,不读写 DOM 信息,也不和浏览器交互(例如通过使用 setTimeout)。
class child extends PureComponent { static propTypes = { value: PropTypes.bool.isRequired }; constructor(props) { super( props); this.state = { value: false }; } render() { this.state = { value: this.props.value }; changeValue = () => { this.setState({ value: false }); } return ( <div style={{ display: value ? 'block':'none' }}> <img src={src} alt="" /> <div className={styles.value}>这是父组件的传值:{value}</div> <div className={styles['icon-close']} onClick={changeValue}> <img src={close} alt="" /> </div> </div> ); } } export default Child;

