Javascript 将输入字段绑定到网格组件

Javascript 将输入字段绑定到网格组件,javascript,reactjs,data-binding,Javascript,Reactjs,Data Binding,如何将SearchFilter的值与FilterGrid同步,以便过滤数据(请参见下面的代码)?键入时,字段清除值时出现问题。我使用状态钩子的方式肯定有问题 问题可能是由于我调用onChange的方式导致的,该函数位于SearchFilter中的handleOnChange函数内部。我将onChange“listener”作为属性传递给筛选器,以便可以访问筛选器外部的值 不确定这是否是正确的方法,因为将值directy绑定到网格内的搜索字段会给我以下警告: 警告:组件正在将受控输入更改为非受控输

如何将
SearchFilter
的值与
FilterGrid
同步,以便过滤数据(请参见下面的代码)?键入时,字段清除值时出现问题。我使用状态钩子的方式肯定有问题

问题可能是由于我调用
onChange
的方式导致的,该函数位于
SearchFilter
中的
handleOnChange
函数内部。我将
onChange
“listener”作为属性传递给筛选器,以便可以访问筛选器外部的值

不确定这是否是正确的方法,因为将值directy绑定到网格内的搜索字段会给我以下警告:

警告:组件正在将受控输入更改为非受控输入。这可能是由值从定义更改为未定义引起的,这是不应该发生的。请在组件的生命周期内决定使用受控或非受控输入元素


以下是指向实时沙盒的链接:

App.jsx package.json
{
“依赖项”:{
“@material ui/core”:“4.11.1”,
“材料表”:“1.69.2”,
“道具类型”:“15.7.2”,
“反应”:“17.0.0”,
“react dom”:“17.0.0”
}
}
index.html

反应材料界面搜索

问题在于执行以下操作时setState的异步性质:

  const handleOnChange = (e) => {
    setInternalValue(e.target.value);
    onChange(internalValue);
  };
一旦执行
onChange
更新状态(它不等待setInternalValue),internalValue仍然为空

还有其他的事情要考虑。您正在复制状态,这不是好的做法。您最好将过滤器状态保持在
FilterGrid
并作为道具传递

我注意到的另一件事是,输入上的每种类型都会模糊输入字段。如果在外部声明工具提示,并且不作为组件参数传递到
FilterGrid

FilterGrid

import React, { useState } from "react";
import SearchFilter from "./SearchFilter";
import MaterialTable from "material-table";

const Toolbar = ({ filterValue, setFilterValue }) => (
  <div
    style={{
      display: "flex",
      flex: 1,
      flexDirection: "row",
      justifyContent: "flex-end"
    }}
  >
    <SearchFilter filterValue={filterValue} setFilter={setFilterValue} />
  </div>
);

const FilterGrid = (props) => {
  const { data, columns } = props;
  const [filterValue, setFilterValue] = useState("");

  const applyFilter = (records) =>
    records.filter((record) =>
      Object.values(record).some((value) => `${value}`.includes(filterValue))
    );

  console.log("Changed filter:", filterValue);

  return (
    <div>
      <Toolbar filterValue={filterValue} setFilterValue={setFilterValue} />
      <MaterialTable
        data={applyFilter(data)}
        columns={columns}
        options={{
          search: false
        }}
      />
    </div>
  );
};

export default FilterGrid;
import React,{useState}来自“React”;
从“/SearchFilter”导入SearchFilter;
从“物料表”中导入物料表;
常量工具栏=({filterValue,setFilterValue})=>(
);
常量过滤器网格=(道具)=>{
const{data,columns}=props;
常量[filterValue,setFilterValue]=使用状态(“”);
常量applyFilter=(记录)=>
records.filter((记录)=>
Object.values(record.some((value)=>`${value}`。包括(filterValue))
);
log(“更改的筛选器:”,filterValue);
返回(
);
};
导出默认FilterGrid;
搜索过滤器

import { FormControl, Input } from "@material-ui/core";
import React from "react";
import PropTypes from "prop-types";

const SearchFilter = (props) => {
  const { filterValue, setFilter } = props;

  const handleOnChange = (e) => {
    setFilter(e.target.value);
  };

  return (
    <FormControl>
      <Input
        type="search"
        placeholder="Search..."
        onChange={handleOnChange}
        value={filterValue}
      />
    </FormControl>
  );
};

SearchFilter.propTypes = {
  filterValue: PropTypes.string.isRequired,
  setFilter: PropTypes.func.isRequired
};

export default SearchFilter;
从“@material ui/core”导入{FormControl,Input}”;
从“React”导入React;
从“道具类型”导入道具类型;
const SearchFilter=(道具)=>{
常量{filterValue,setFilter}=props;
常数变化=(e)=>{
设置过滤器(如目标值);
};
返回(
);
};
SearchFilter.propTypes={
filterValue:PropTypes.string.isRequired,
setFilter:PropTypes.func.isRequired
};
导出默认搜索过滤器;

问题在于执行以下操作时setState的异步性质:

  const handleOnChange = (e) => {
    setInternalValue(e.target.value);
    onChange(internalValue);
  };
一旦执行
onChange
更新状态(它不等待setInternalValue),internalValue仍然为空

还有其他的事情要考虑。您正在复制状态,这不是好的做法。您最好将过滤器状态保持在
FilterGrid
并作为道具传递

我注意到的另一件事是,输入上的每种类型都会模糊输入字段。如果在外部声明工具提示,并且不作为组件参数传递到
FilterGrid

FilterGrid

import React, { useState } from "react";
import SearchFilter from "./SearchFilter";
import MaterialTable from "material-table";

const Toolbar = ({ filterValue, setFilterValue }) => (
  <div
    style={{
      display: "flex",
      flex: 1,
      flexDirection: "row",
      justifyContent: "flex-end"
    }}
  >
    <SearchFilter filterValue={filterValue} setFilter={setFilterValue} />
  </div>
);

const FilterGrid = (props) => {
  const { data, columns } = props;
  const [filterValue, setFilterValue] = useState("");

  const applyFilter = (records) =>
    records.filter((record) =>
      Object.values(record).some((value) => `${value}`.includes(filterValue))
    );

  console.log("Changed filter:", filterValue);

  return (
    <div>
      <Toolbar filterValue={filterValue} setFilterValue={setFilterValue} />
      <MaterialTable
        data={applyFilter(data)}
        columns={columns}
        options={{
          search: false
        }}
      />
    </div>
  );
};

export default FilterGrid;
import React,{useState}来自“React”;
从“/SearchFilter”导入SearchFilter;
从“物料表”中导入物料表;
常量工具栏=({filterValue,setFilterValue})=>(
);
常量过滤器网格=(道具)=>{
const{data,columns}=props;
常量[filterValue,setFilterValue]=使用状态(“”);
常量applyFilter=(记录)=>
records.filter((记录)=>
Object.values(record.some((value)=>`${value}`。包括(filterValue))
);
log(“更改的筛选器:”,filterValue);
返回(
);
};
导出默认FilterGrid;
搜索过滤器

import { FormControl, Input } from "@material-ui/core";
import React from "react";
import PropTypes from "prop-types";

const SearchFilter = (props) => {
  const { filterValue, setFilter } = props;

  const handleOnChange = (e) => {
    setFilter(e.target.value);
  };

  return (
    <FormControl>
      <Input
        type="search"
        placeholder="Search..."
        onChange={handleOnChange}
        value={filterValue}
      />
    </FormControl>
  );
};

SearchFilter.propTypes = {
  filterValue: PropTypes.string.isRequired,
  setFilter: PropTypes.func.isRequired
};

export default SearchFilter;
从“@material ui/core”导入{FormControl,Input}”;
从“React”导入React;
从“道具类型”导入道具类型;
const SearchFilter=(道具)=>{
常量{filterValue,setFilter}=props;
常数变化=(e)=>{
设置过滤器(如目标值);
};
返回(
);
};
SearchFilter.propTypes={
filterValue:PropTypes.string.isRequired,
setFilter:PropTypes.func.isRequired
};
导出默认搜索过滤器;

因此无法通过组件将工具栏设置为网格形式。toolbar=()=>()?我不知道。您希望的方法强制在工具栏上重新渲染,导致每个用户类型的SeachField模糊。因此,无法通过
组件将工具栏设置为网格。ToolBar=()=>()
?我不知道。您所希望的方法强制工具栏上的重新渲染器在每个用户类型的SeachField上产生模糊。