【问题标题】:React replacing array of objects with a new array of objects of the same type反应用相同类型的新对象数组替换对象数组
【发布时间】:2019-07-10 02:27:00
【问题描述】:

所以我有一个数组是一个类的状态。我们称它为 A。A 通过构造函数中的函数 f 填充了 B 类型的对象。稍后,我使用 f 和新数据生成一个名为 C 的 B 类型对象的新数组。然后我使用 setState({A: C})。但是,这会导致来自第一个阵列的数据保留在显示器上。我完全不知道如何解决这个问题。

编辑:代码 sn-ps

class ClassBox extends Component {
constructor(props) {
    super(props);
    // note data here uses the keys from the config file
    this.state = {
        data: this.props.data,
        filteredData: [],
        functionData: []
    };
    this.generateFunctionData = this.generateFunctionData.bind(this);
    this.state.functionData = this.generateFunctionData();
    this.state.filteredData = this.state.functionData;
    this.handleSearch = this.handleSearch.bind(this);
}

generateFunctionData(useData = false, data = null){
   return useData ? ProcessJSON.extractFunctions(data.functions).map((_function, index) =>
   {return createMethodBox(_function.Func_name, _function.Description, _function.Access_Mod, index)}) : ProcessJSON.extractFunctions(this.props.data.functions).map((_function, index) =>
   {return createMethodBox(_function.Func_name, _function.Description, _function.Access_Mod, index)});
}

handleSearch(input) {
    // convert to lower case to avoid capitalization issues
    const inputLowerCase = input.toString().toLowerCase();
    // filter the list of files based on the input
    const matchingList = this.state.functionData.filter((method) => {
            return method.props.name.toLowerCase().includes(inputLowerCase)
        }
    );
    this.setState({
        filteredData: matchingList
    });
}

render() {
    console.log(this.state.filteredData)
    return (
        <Container>
            <NameContainer>
                <h1>{this.state.data.className}</h1>
            </NameContainer>
            <ContentContainer>
                <DescriptionContainer>
                    {this.state.data.description}
                </DescriptionContainer>
                <StyledDivider/>
                <VarContainer>
                    <h1>Variables</h1>
                    <VarTableContainer>
                        <BootstrapTable
                            keyField="id"
                            data={[]}
                            columns={testColumns}
                            bordered={false}
                            noDataIndication="Table is Empty"
                            classes="var-table"
                        />
                    </VarTableContainer>
                    {/*{this.state.data.variables}*/}
                </VarContainer>
                <StyledDivider/>
                <MethodContainer>
                    <MethodHeader>
                        <h1>Methods</h1>
                        <StyledSearchBar onSearch={this.handleSearch}
                                         isDynamic={true} allowEmptySearch={false} minChars={0}
                                         className='searchBar'/>
                    </MethodHeader>
                    <Methods>
                        {this.state.filteredData}
                    </Methods>
                </MethodContainer>
            </ContentContainer>
        </Container>
    );
}


class Classes extends Component {
constructor(props) {
    super(props);
    this.state = {
        data: this.props.data,
        displayIndex: this.props.displayIndex
    };
    this.treeData = createTreeData(this.state.data);
    this.classBox = null
}

componentDidUpdate(prevProps, prevState, snapshot) {
    if(prevState.displayIndex !== this.props.displayIndex){
        const funcData = this.classBox.generateFunctionData(true, this.state.data[0][this.props.displayIndex]);
        console.log(funcData);
        this.classBox.setState({data: this.state.data[0][this.props.displayIndex], functionData: funcData, filteredData: funcData });
        this.classBox.forceUpdate();
        this.setState({displayIndex: this.props.displayIndex});
    }
}

render() {
    this.treeData = createTreeData(this.state.data);
    return (
        <Container>
            <FileTreeContainer>
                <StyledTreeMenu data={treeData}/>
            </FileTreeContainer>
            <ClassInfoContainer>
                <ClassBox ref = {el => this.classBox = el} data = {this.state.data[0][this.state.displayIndex]}/>
            </ClassInfoContainer>
        </Container>
    )
}

Classes 包含 ClassBox 的一个实例。执行 componentDidUpdate 后,页面仍然显示旧的方法框,即使 functionData 发生了变化。

编辑 2:还值得注意的是,当我用着陆视图替换类视图并返回到类视图时,它会正确显示页面。

【问题讨论】:

  • 能否提供一个react组件的sn-p代码?
  • 我认为我已经很好地抽象了这个问题。我很困惑为什么重新分配给处于状态的对象和调用渲染不会更新网页,因为它应该

标签: javascript reactjs ecmascript-6


【解决方案1】:

您设置状态的方式应该是正确的,因为您将其设置为从 .filter 中新创建的数组。

我认为问题在于您将方法组件存储在过滤数据状态中。 Components should not be stored in state.

我相信您的组件只是重新渲染,而不是删除旧生成的组件。也许尝试将搜索输入映射到状态并以这种方式生成方法组件。

【讨论】:

  • 如何正确移除旧组件?
  • 另外,当我在render中完成渲染时,它仍然无法正确更新。
  • 我认为您可能必须重新渲染整个子组件。尝试将过滤数据存储为父组件的状态,并向子组件传递一个回调函数,允许您从子组件修改父过滤数据状态。
  • 如何重新渲染整个子组件?
猜你喜欢
  • 2020-11-16
  • 2014-06-18
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 2017-02-14
  • 2020-01-16
  • 2013-08-18
  • 1970-01-01
相关资源
最近更新 更多