Open msforest opened 6 years ago
简便的方法就是把B组件设为无状态的组件,所有状态全部放在A组件里,增加删除什么的方法全部写在A组件里,这是一种不好的写法,违背了react的component思想。该属于B组件的操作的状态和方法都应该写在自身组件里。
但是,B组件数据来源A组件,修改了B的数据也要同时修改A的数据,修改了A的数据还要同时反映到B的数据,也就是同一份数据需要应用到两个组件。使用第三方库时,每次打开B组件时B都被重新Mount/Unmount。
S1: A把数据组装成对象:[{}, ...], B直接修改props的数据【ps:一直以为props是read only,没想到object还是可以修改,看来还是没用摆脱js的引用】
[{}, ...]
class B extends React.Component{ constructor(props) { super(props); this.state = { tags: [...this.props.tags] } } handleChange(tag) { this.setState((prevState) => prevState.tags.map((tagItem) => { if (tagItem.key === tag.key) { if (!tag.selected && this.props.handleAdd) { this.props.handleAdd(tag.key); } else if (tag.selected && this.props.handleDelete) { this.props.handleDelete(tag.key); } tagItem.selected = !tagItem.selected; } return tagItem; })) } render(){ const selectedTags = [], unselectedTags = []; props.tags.forEach((tag) => { if (tag.selected) { selectedTags.push((<CheckableTag key={tag.key} checked={false} onChange={(checked) => this.handleChange(tag)} style={tagStyle} > {tag.tag || 'N/A'} </CheckableTag>)) } else { unselectedTags.push(( <CheckableTag key={tag.key} checked={false} onChange={(checked) => this.handleChange(tag)} style={tagStyle} > {tag.tag || 'N/A'} </CheckableTag> )) } }) return ( <div> <Panel header="Selected Columns" bsStyle="success"> {selectedTags} </Panel> <Panel header="Unselected Columns" bsStyle="danger"> {unselectedTags} </Panel> </div> ); } } class A extends React.Component{ constructor(props){ super(props) this.state = { data: [{}, ...] } } handleDelete(){ // this.state.data.splice(index, 1) } handleAdd(){ // this.state.data.push() } render(){ return (<OverlayTrigger trigger='click' placement="bottom" overlay={ <Popover id="tooltip" title="Columns Filter"> <ColumnTag data={this.data} handleDelete={this.handleDelete} handleAdd={this.handleAdd}/> </Popover> } rootClose={true}> <Button bsStyle="primary" >Columns Filter</Button> </OverlayTrigger>) } }
S2: 在A组件里获取B组件实例,再次加载时使用上一次保存的实例
class B extends React.Component { constructor(props) { super(props); this.state = { tags: [...this.props.data], } } handleChange(tag, checked) { const tags = this.state.tags; const find = tags.find(item=>item.key===tag.key); if (checked) { find.flag = true; this.props.handleAdd.call(this, tag.key); } else { find.flag = false; this.props.handleDelete.call(this, tag.key); } this.setState({tags: [...tags]}) } render() { const { tags } = this.state; const selectedTags=[], unselectedTags = []; tags.forEach(tag=>{ if(tag.flag){ selectedTags.push(<CheckableTag key={tag.key} checked={false} onChange={(checked) => this.handleChange(tag, false)} style={tagStyle} > {tag.tag||'N/A'} </CheckableTag>) }else{ unselectedTags.push(<CheckableTag key={tag.key} checked={false} onChange={(checked) => this.handleChange(tag,true)} style={tagStyle} > {tag.tag||'N/A'} </CheckableTag>) } }) return ( <div className={css.tag}> <h2>{this.props.title}</h2> <h3>Selected Columns</h3> {selectedTags} <h3>Unselected Columns</h3> {unselectedTags} </div> ); } } B.propTypes = { title: PropTypes.string.isRequired, handleDelete: PropTypes.func.isRequired, handleAdd: PropTypes.func.isRequired, } class A extends React.Component{ constructor(props){ super(props) this.state = { data: [{}, ...], colContent: 'test', } } handleDelete(){ // this.state.data.splice(index, 1) } handleAdd(){ // this.state.data.push() } columnFilter = ()=>{ let colContent = <span></span>; if(!React.isValidElement(this.state.colContent)){ colContent = <Popover id="tooltip" style={{maxWidth: '50%', maxHeight: '60%', left: '40%'}}> <B title="Columns Filter" data={this.state.tags} handleDelete={this.handleDelete} handleAdd={this.handleAdd}/></Popover> this.setState({colContent}) }else{ colContent = this.ref._overlay.props.children //【此种方式可以保存instance】 this.setState({colContent}) } } render(){ return ( <OverlayTrigger ref={node=>this.ref=node} trigger='click' placement="bottom" overlay={this.state.colContent} rootClose={true}> <Button bsStyle="primary" onClick={this.columnFilter}>Columns Filter</Button> </OverlayTrigger>) } }
简便的方法就是把B组件设为无状态的组件,所有状态全部放在A组件里,增加删除什么的方法全部写在A组件里,这是一种不好的写法,违背了react的component思想。该属于B组件的操作的状态和方法都应该写在自身组件里。
但是,B组件数据来源A组件,修改了B的数据也要同时修改A的数据,修改了A的数据还要同时反映到B的数据,也就是同一份数据需要应用到两个组件。使用第三方库时,每次打开B组件时B都被重新Mount/Unmount。
S1: A把数据组装成对象:
[{}, ...]
, B直接修改props的数据【ps:一直以为props是read only,没想到object还是可以修改,看来还是没用摆脱js的引用】S2: 在A组件里获取B组件实例,再次加载时使用上一次保存的实例