为什么组件在调用 setState() 后不更新它们的内容?

Why are components not updating their content after a call to setState()?

我正在尝试使用 React 在一个简单的页面中显示特定于用户的数据。但是,即使能够使用 axios 获取用户数据进行 HTTP 请求并调用 setState() 更新根组件的状态,页面中显示的数据仍然没有改变。

这里是主要组件的代码:

    class UserPage extends React.Component {
    constructor (props) {
        super (props)

        this.state = {userId: null, username: null, clientId: null, jobs: null}
    }

    componentDidMount () {
        getSessionUserData ()
        .then (res => {
            this.setState({userId: res.data.id, username: res.data.username, clientId: res.data.client_id})
        })
    }

    render () {
        console.log ("rendering", this.state)
        return (
            <div id="user-page">
                <PageHeader text={"Welcome, " + this.state.username} id="user-page-header"/>
            </div>
        )
    }
}

如您所见,PageHeader 从主要组件的状态中获取数据。这是 PageHeader 组件的代码:

export class PageHeader extends React.Component {
    constructor (props) {
        super(props)

        this.state = {text: props.text}
    }

    render () {
        console.log ("rendering header with text: ", this.props.text)
        return (
            <h1 id={this.props.id}>{this.state.text}</h1>
        )
    }
}

我在 UserPage 组件的 render() 方法中添加了 console.log() 以检查它是否在 setState() 之后被调用并确保状态已经updated,结果确实被调用了,state也确实被更新了。这是我重新加载页面时控制台打印出的图像:

Image showing page and console output

在图像中您可以看到 render() 方法在 setState() 之后再次被调用并且状态具有新的用户数据。此外,我为 PageHeader 组件的 render() 方法添加了控制台日志,以检查是否由于某种原因它没有被重新渲染,但它们正在打印并使用正确的文本,所以我不这样做很明白为什么页面中的数据没有变化。你能帮我弄清楚为什么会这样吗?

您正在传递给

<h1 id={this.props.id}>{this.state.text}</h1>

在构造函数中设置的状态。使用初始道具调用构造函数一次。由于您将 ID 设置为组件,因此不会重新创建(重用)。你打印 this.props.text 但渲染 this.state.text。因此,您要么必须实施 'componentDidUpdate' 以对 props 更改做出反应并在那里更新您的状态,要么只需将 <h1 id={this.props.id}>{this.state.text}</h1> 替换为 <h1 id={this.props.id}>{this.props.text}</h1>

如果您在 h1 标签中使用 this.props.text 而不是 this.state.text,那么它应该可以工作。 PageHeader 组件中的状态是在构造函数上设置的,这只会在组件创建时发生,在第二次渲染时不会 re-set。

export class PageHeader extends React.Component {
    constructor (props) {
        super(props)

        this.state = {text: props.text}
    }

    render () {
        console.log ("rendering header with text: ", this.props.text)
        return (
            <h1 id={this.props.id}>{this.props.text}</h1>
        )
    }
}