【问题标题】:React Not Instantiating New ComponentReact 不实例化新组件
【发布时间】:2018-10-24 23:09:10
【问题描述】:

所以我有一个反应组件,它根据 URL 指向的位置呈现不同的锚点。基本上,服务器上有一个文件可以是普通文件,也可以是包含 URL 的文本文件。如果它包含一个普通文件,我希望 href 是文件的位置。如果它是一个带有 URL 的文本,我希望它指向那个 URL。我有一个我想要显示的这些文件的列表,有时会根据状态和一大堆其他内容填充完全不同的条目。所以本质上逻辑是这样的:

listOfFiles.map((file, index) => {
    return (
           <FileAnchor
            file={file}
            methodToCheckFileType={theMethodToCheckFileType}
           />
    );
});

class FileAnchor extends React.Component {
    constructor(props){
        super(props);

        this.state = {
            file: props.file,
            url: null
        }

        this.methodToCheckFileType = props.methodToCheckFileType;
    }

    componentDidMount(){
        this.methodToCheckFileType(this.state.file)
        .then(response => {
            this.setState({
                url: response.url
            });
        })
    }

    render(){
        return this.state.url !== null && (
            <a href={this.state.url}>{this.state.file.filename</a>
        );
    }
}

export default FileAnchor;

加载第一个列表时效果很好。一切都按预期工作。但是,当列表被清空并重新填充不同的文件时,不会删除第一个列表中的条目。我已经调试过了,listOfFiles 变量包含所有新文件,没有旧文件。发送到FileAnchor 的道具都是新文件。然而,FileAnchor 的构造函数并没有被第一个调用,但是第一个列表中有很多条目。如果第一个列表中有 4 个条目,下一个列表中有 6 个条目。前四个将来自第一个列表,后两个将来自第二个列表。

所以基本上,FileAnchor 组件正在被重用?我无法想象为什么在向他们发送不同的道具时会出现这种情况。任何人都可以帮助阐明这一点吗?我觉得这可能是我没有掌握的 ReactJS 工作原理的一些基本原则。如果您需要更多信息,请告诉我。

【问题讨论】:

    标签: javascript reactjs react-native ecmascript-6


    【解决方案1】:

    这可能是由于生命周期方法componentDidMount() 每个组件实例仅被调用一次。在这种情况下,我感觉 react 会在可能的情况下尝试重用组件实例,这意味着当您的 listOfFiles 在单个渲染周期中被清空/重新填充时,不会调用 componentDidMount()

    尝试将以下方法添加到您的组件中:

    componentWillReceiveProps(nextProps) {
    
        // If the incoming file prop doesn't match the current file
        // prop of this component instance, update internal state via
        // setState to trigger a re-render, and call methodToCheckFileType()
        // as in your componentDidMount() method
        if(nextProps.file !== this.props.file) {
    
        this.setState({ file : nextProps.file })         
    
        this.methodToCheckFileType(nextProps.file)
        .then(response => {
            this.setState({
                url: response.url
            });
        })
        }
     }
    

    【讨论】:

    • 这解决了我的问题!非常感谢,我正在努力弄清楚为什么它没有更新。
    猜你喜欢
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 2017-03-18
    相关资源
    最近更新 更多