输入字段失去对每种字符类型的关注 - 反应 [英] Input field losing focus on each character type - react

查看:34
本文介绍了输入字段失去对每种字符类型的关注 - 反应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在表格标题上添加列过滤器,但在每次输入字段后,它都会失去焦点.

我的主要组件:这里,我初始化了一个本地状态:searchColArrfetchData 中使用的所有其他状态都是 redux 状态,它们正在使用 useSelectror

Category.jsx

const [searchColArr, setSearchColArr] = useState({名称:",});//所有这些默认值要么是本地状态要么是redux状态函数 fetchData(newPage = 页,newPerPage = 每页,新订单 = 订单,新目录 = 目录,newSearchColArr = searchColArr,新搜索 = 搜索){派遣(列表类别(新页面,新每页,新命令,新目录,newSearchColArr,新搜索));}const headerRow = React.useMemo(() =>[{标题:名称",名称:名称",过滤器:真实,排序:真实,},{标题:动作",名称:id",过滤器:假,排序:假,},],[]);const TBody = () =>{返回 (<tbody key="tbody">{列表&&list.map((row, i) => (<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]);返回 (<div className="row"><div className="col-md-12">{/* REDUX 表开始 */}<ReduxTable键=redux-table";isLoading={isLoading}headerRow={headerRow}列表={列表}页={页}每页={每页}订单={订单}目录={目录}总计={总计}总页数={总页数}searchColArr={searchColArr}handlePageLengthChange={handlePageLengthChange}handlePageChange={handlePageChange}handleColSearch={handleColSearch}TBody={TBody}/>{/* REDUX 表结束 */}

);

而且,在 Redux Table 中,我正在加载另一个组件 ReduxTableHeader

ReduxTable

const ReduxTable = ({正在加载,标题行,列表,页,每页,命令,目录,全部的,总页数,搜索ColArr,handlePageLengthChange,处理页面更改,句柄ColSearch,身体,}) =>{返回 (<div className="card-box">{/* 表头和正文只是通过列表循环*/}<表id=基本表"className="table table-bordered action-table table-striped table-hover mb-0";>{/* ReduxTableHeader */}<ReduxTableHeader键=redux-table-header";headerRow={headerRow}searchColArr={searchColArr}handleColSearch={handleColSearch}/><Tbody/>

);};

ReduxTableHeader

 返回 (<thead key="thead"><tr>//标题名称列表</tr><tr key="filter-row">{headerRow &&headerRow.map((v, i) => (<th key={v.name}>{v.过滤器?(<输入类型=搜索"className =表单控件表单控件sm d-inline-block";占位符="aria-controls=数据表";名称={v.name}值={searchColArr[v.name] ||""}onChange={handleColSearch}自动完成=关闭"键={索引";+我}/>) : (")}</th>))}</tr></thead>);

这个表头是我加载输入字段的地方,每当我输入这封信时,就会失去自动焦点.我该如何解决?

解决方案

您通过创建像 Tbody 这样的嵌套组件违反了 React 规则.这会在每次渲染时创建新组件(即使函数名称保持不变),并导致该组件重新挂载

在 99.999% 的情况下,您的输入失去焦点是因为它的一个父组件重新挂载,因此每次输入内容时都会创建一个新的组件树(和新的输入元素).您可能正在做与上面组件树中的 Tbody 相同的事情,并且每次触发 fetchData 时,您的整个 Category 组件都会重新安装.为了确认你可以注释掉这个触发 fetchData

useEffect

I am trying to add column filter on the header of the table but after each input typing on the field, it is losing the focus.

My main component: Here, I have initialized a local state: searchColArr and all others state used in fetchData are the redux state, which are being initialized using 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>
);

And, inside Redux Table I am loading another component 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>
    );

This table header is the place where I am loading an input field, and whenever I type on this letter is just losing the auto focus. How could I fix it?

解决方案

You are violating rules of React by creating nested components like Tbody. This creates new component every render (even though function name stays the same), and causes that component to remount

In 99.999% of cases your input loses focus because one of its parent components remounts, thus creating a new component tree (and new input element) every time you type something. You are probably doing the same thing as you do with Tbody above in component tree, and your whole Category component remounts every time you trigger fetchData. To confirm you can comment out this useEffect that triggers fetchData

这篇关于输入字段失去对每种字符类型的关注 - 反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆