React.js中如何避免输入框输入时useState与useLocation触发重渲染
问题本质
你观察到的控制台重复打印是React的正常更新逻辑,不属于bug。当你在输入框输入字符触发setTitle/setContent/setCategory修改组件内部state时,整个EditScreen组件会重新执行,写在组件顶层的console.log(location)自然会跟着每次重渲染执行一次。
可以直接验证逻辑合理性:useState的初始值只会在组件第一次挂载时读取,后续重渲染不会覆盖你已经修改的表单state,输入内容不会被location里的原始数据冲掉,业务逻辑本身是正常可用的。
可选优化方案
1. 仅在组件挂载时打印location数据
如果不需要每次重渲染都打印,可以把日志逻辑放到useEffect中,仅组件初始化时执行一次:
import axios from "axios"; import React, { useState, useEffect } from "react"; import { useLocation } from "react-router"; export const EditScreen = () => { const locationState = useLocation().state; // 仅组件挂载时执行一次 useEffect(() => { console.log(locationState); }, []) const [title, setTitle] = useState(locationState.b_title); const [content, setContent] = useState(locationState.b_content); const [category, setCategory] = useState(locationState.category_id); // 剩余原有业务逻辑保持不变
2. 重渲染性能优化(当前场景不强制需要)
如果后续EditScreen组件复杂度提升、嵌套了大量子组件,输入触发的全局重渲染出现明显性能损耗,可以考虑把输入模块抽离为独立组件、或者用React.memo包裹子组件减少不必要重渲染,你当前的简单表单场景不需要做这层处理。
现有代码隐藏问题
你当前的提交逻辑中,then(alert("success edit blog"))会在请求刚发起时就立即执行alert,不会等待接口返回结果,需要修改为回调函数形式:
axios .put(`http://localhost:3001/api/v1/blog/${locationState.id}`, { blog_title: title, blog_content: content, category_id: category, }) .then(() => alert("success edit blog")) // 用箭头函数包裹,请求成功后再执行 .catch((err) => alert(err));
内容的提问来源于stack exchange,提问作者Muhammad Haekal
相关产品推荐
相关产品推荐

