首页 > 解决方案 > 如何防止子组件重新渲染?

问题描述

我的搜索栏组件更改了布局组件的状态。因此,Layout 组件会触发其所有子组件的重新渲染。我尝试实现 React.memo(),但对我没有帮助。请纠正我。先感谢您!

布局组件:

export default class Layout extends Component {
    state = {
        cityName: "",
        date: "",
        icon: "",
    };

    searchbarSubmitHandler = e => {
        const cityName =
            e.target.children[0].firstChild.children[0].value;
        this.setState({
            cityName: cityName
        });
        console.log(this.state.cityName);
        e.preventDefault();
    };

    searchbarChangeHandler = e => {
        this.setState({
            cityName: e.target.value
        });
    };
    render() {
        return (
            <div>
                <Searchbar
                    submit={this.searchbarSubmitHandler}
                    change={this.searchbarChangeHandler}
                />
                <Switch>
                    <Route
                        exact
                        path="/"
                        component={() =>
                            <CurrentWeather icon={this.state.icon} />
                        }
                    />
                    <Route
                        path="/24h-weather"
                        component={HourlyWeather}
                    />
                </Switch>
            </div>
        );
    }
}

搜索栏组件:

const searchbar = props => {
    return (
        <div className="searchbar">
            <form onSubmit={props.submit}>
                <div className="inputs">
                    <div className="inputTextWrapper">
                        <input
                            className="inputText"
                            type="text"
                            placeholder="City name..."
                            onChange={props.change}
                        />
                    </div>

                    <input
                        className="inputSubmit"
                        type="submit"
                        value="Search"
                    />
                </div>
            </form>
        </div>
    );
};

export default searchbar;

我不想重新渲染的 CurrentWeather 组件:

const currentWeather = props => {
    return (
        <div className="container">
            <h3>London, UK</h3>
            <img
              src={`http://openweathermap.org/img/wn/${props.icon}.png`}
              alt="weather icon"
            />
        </div>
    );
};

const areEqual = (prevProps, nextProps) => prevProps === nextProps;

export default React.memo(currentWeather, areEqual);

标签: javascriptreactjsoptimizationreact-hooks

解决方案


问题是

<Route
    exact
    path="/"
    component={() => <CurrentWeather icon={this.state.icon} />}
    />

工作方式component是“路由器使用 React.createElement 从给定组件创建一个新的 React 元素。现有组件被卸载并安装新组件,而不是仅仅更新现有组件”

https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Route.md#component

如果将其更改为render,则不会获得此效果,并且不会重新创建此组件。

<Route
    exact
    path="/"
    render={() => <CurrentWeather icon={this.state.icon} />}
    />

https://codesandbox.io/s/restless-hill-2ykhq来展示这个工作


推荐阅读