输入字段失去对每个字符类型的关注 - 反应
Posted
技术标签:
【中文标题】输入字段失去对每个字符类型的关注 - 反应【英文标题】:Input field losing focus on each character type - react 【发布时间】:2021-08-02 12:56:42 【问题描述】:我正在尝试在表格的标题上添加列过滤器,但在字段上每次输入后,它就会失去焦点。
我的主要组件:在这里,我初始化了一个本地状态:searchColArr
,fetchData
中使用的所有其他状态都是 redux 状态,正在使用 useSelectror
进行初始化
Category.jsx
const [searchColArr, setSearchColArr] = useState(
name: "",
);
//all these default value are either local state or redux state
function fetchData(
newPage = page,
newPerPage = perPage,
newOrder = order,
newDir = dir,
newSearchColArr = searchColArr,
newSearch = search
)
dispatch(
listCategory(
newPage,
newPerPage,
newOrder,
newDir,
newSearchColArr,
newSearch
)
);
const headerRow = React.useMemo(
() => [
header: "Name",
name: "name",
filter: true,
sort: true,
,
header: "Action",
name: "id",
filter: false,
sort: false,
,
],
[]
);
const TBody = () =>
return (
<tbody key="tbody">
list &&
list.map((row, i) => (
<tr key=row.id>
<td>row.name</td>
<td>
<ActionColumn id=row.id />
</td>
</tr>
))
</tbody>
);
;
const handleColSearch = ( currentTarget: input ) =>
setSearchColArr(
...searchColArr,
[input.name]: input.value,
);
;
useEffect(() =>
fetchData();
, [searchColArr]);
return (
<div className="row">
<div className="col-md-12">
/* REDUX TABLE STARTS */
<ReduxTable
key="redux-table"
isLoading=isLoading
headerRow=headerRow
list=list
page=page
perPage=perPage
order=order
dir=dir
total=total
totalPage=totalPage
searchColArr=searchColArr
handlePageLengthChange=handlePageLengthChange
handlePageChange=handlePageChange
handleColSearch=handleColSearch
TBody=TBody
/>
/* REDUX TABLE ENDS */
</div>
</div>
);
而且,在 Redux Table 中,我正在加载另一个组件 ReduxTableHeader
ReduxTable
const ReduxTable = (
isLoading,
headerRow,
list,
page,
perPage,
order,
dir,
total,
totalPage,
searchColArr,
handlePageLengthChange,
handlePageChange,
handleColSearch,
TBody,
) =>
return (
<div className="card-box">
/* TABLE HEADER AND BODY just looping thorugh list*/
<table
id="basicTable"
className="table table-bordered action-table table-striped table-hover mb-0"
>
/* ReduxTableHeader */
<ReduxTableHeader
key="redux-table-header"
headerRow=headerRow
searchColArr=searchColArr
handleColSearch=handleColSearch
/>
<TBody />
</table>
</div>
);
;
ReduxTableHeader
return (
<thead key="thead">
<tr>
//list of header name
</tr>
<tr key="filter-row">
headerRow &&
headerRow.map((v, i) => (
<th key=v.name>
v.filter ? (
<input
type="search"
className="form-control form-control-sm d-inline-block"
placeholder=""
aria-controls="datatable"
name=v.name
value=searchColArr[v.name] || ""
onChange=handleColSearch
autoComplete="off"
key="index" + i
/>
) : (
""
)
</th>
))
</tr>
</thead>
);
这个表头是我加载输入字段的地方,每当我在这个字母上输入时,都会失去自动焦点。我该如何解决?
【问题讨论】:
每次调用handleColSearch
后,您的组件可能会重新渲染。如果没有更多背景信息,将很难进一步诊断。
你想看哪个文件,请告诉我。
见***.com/questions/22573494/…
如果可能,请添加代码沙箱链接。
【参考方案1】:
您通过创建像 Tbody
这样的嵌套组件违反了 React 规则。这会在每次渲染时创建新组件(即使函数名称保持不变),并导致该组件重新挂载
在 99.999% 的情况下,您的输入失去焦点是因为它的一个父组件重新挂载,因此每次您输入内容时都会创建一个新的组件树(和新的输入元素)。您可能正在做与上面组件树中的 Tbody 相同的事情,并且每次触发 fetchData
时都会重新安装整个 Category
组件。要确认您可以注释掉这个触发fetchData
的useEffect
【讨论】:
将键设置为索引也会导致重新挂载。还有那些 @Max 抱歉回复晚了。我明白你想说什么。但是,如果我评论了那部分,我怎么能在输入字段上调用 keyup 上的数据。 @AayushDahal 您需要按照反应规则重写整个事情。评论该部分不是解决方案,而只是确认重新安装导致失去焦点的一种方式 @Max 你有资源链接吗?我可以按照哪个正确添加列过滤器?如果你有一个这样的资源链接,你能分享一个吗?【参考方案2】:由于input
组件失去焦点,这意味着它被重新渲染。仅当输入组件之一已更改类型或更改上层树时才会发生这种情况。在这种情况下,react 确实完成了重新渲染。
所以我猜每个渲染都定义了一个父组件 [ReduxTable, ReduxTableHeader]。就像你为 TBody 做的那样。
在这种情况下,React 认为它是一种新型组件并破坏了先前的树并执行完整的重新渲染,这会导致性能滞后,并且在您的情况下会使输入失去焦点。
关于性能,您不应该在函数内部定义组件。 它使反应变得愚蠢。
为了防止这种情况,您需要确保所有输入的父组件都在 Render 函数之外定义。在这种情况下,在函数组件之外。
请查看我的代码沙箱链接,该链接演示了 2 个案例。
-
当您尝试编辑第一行输入时,它不会失去焦点
当您尝试编辑 TBody 中的其他输入时,将失去焦点
也许你也有同样的问题。
https://codesandbox.io/s/react-playground-rvikz?file=/src/App.js:567-572
【讨论】:
【参考方案3】:为您的输入指定一个唯一键将导致 React 重用它而不是重绘它。所以在设置视图状态后应该保持焦点。
return (
<thead>
<tr>
/list of header name
</tr>
<tr>
headerRow &&
headerRow.map((v, i) => (
<th key=v.name>
v.filter ? (
<input
type="search"
className="form-control form-control-sm d-inline-block"
placeholder=""
aria-controls="datatable"
name=v.name
value=searchColArr[v.name] || ""
onChange=handleColSearch
autoComplete="off"
key='input' + i
/>
) : (
""
)
</th>
))
</tr>
</thead>
);
看看this post
【讨论】:
在输入中添加键并不能解决问题,您能否再看一下代码,可能是因为重新渲染父元素?在每种类型上,它都会进行 api 调用,并且由于列表上的更新,整个表格组件可能会重新呈现。 您可能必须在所有父元素上指定一个键属性 我已经更新了代码并展示了我如何为每个父组件添加密钥,但仍然是同样的问题。以上是关于输入字段失去对每个字符类型的关注 - 反应的主要内容,如果未能解决你的问题,请参考以下文章
PDOStatement::fetchAll() 返回的数组中的每个字段都是字符串类型(PHP + MySQL)。如何保留原始字段类型?