首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Set状态不更新下拉复选框使用钩子。

Set状态不更新下拉复选框使用钩子。
EN

Stack Overflow用户
提问于 2019-10-14 19:56:07
回答 2查看 900关注 0票数 1

我是新的反应,我正在建立一个网站,用户可以选择一个特定的类别(又名jurisdiction)在复选框下拉和写一个query在搜索栏。

我父母和孩子的关系是:

代码语言:javascript
复制
Searchform (parent)
     Dropdown (child of Searchform)
     Searchbar (child of Searchform)

我的seachbar工作得很好。(How to pass state from child to parent with Hooks)

然而,

我无法使我的Dropdown工作。特别是:

  • 所有的复选框都被选中(不应该是这样),
  • setJurisdicitons没有工作,因为它console.log()单词Choose...,而不是我实际检查的内容。每当我按下表单中的submit按钮时,都会发生这种情况。

仿形

代码语言:javascript
复制
 function Searchform() {
     function handleSubmit() {
       console.log(query);
       console.log(jurisdictions)
     }

     const [query, setQuery] = useState('');
     const [jurisdictions, setJurisdictions] = useState(["Choose..."]);

     const onChangeQuery = useCallback(
       event => setQuery(event.target.value),
       [],
     );

     const onChangeDropdown = useCallback(
       event => setJurisdictions(event.target.value),
       [],
     );

     return(
       <form onSubmit={handleSubmit}>
         <div className="searchbar-dropdown">
           <div className="searchbar">
           <Searchbar value={query} onChange={onChangeQuery} />
           </div>
           <div className="dropdown">
             <Dropdown value={jurisdictions} onChange={onChangeDropdown}/>
           </div>
         </div>
         <Button variant="contained" color="primary" type="submit">
           Submit your search
         </Button>
       </form>
     )
   }



   export default Searchform;

Dropdown.js

代码语言:javascript
复制
const jurisdictions_list = [
  'Jurisdiction 1',
  'Jurisdiction 2',
  'Jurisdiction 3',
  'Jurisdiction 4',
  'Jurisdiction 5',
];



function Dropdown({ value, onChange }) {
  const classes = useStyles();
  const theme = useTheme();
  console.log("trytrytry")

  console.log(value)
  const handleChange = event => {
    console.log(value);
  };


  return (
    <div className={classes.root}>
      <FormControl className={classes.formControl}>
        <InputLabel htmlFor="select-multiple-checkbox">Jurisdiction</InputLabel>
        <Select
          multiple
          value={value}
          onChange={onChange, handleChange}
          input={<Input id="select-multiple-checkbox" />}
          renderValue={selected => selected.join(', ')}
          MenuProps={MenuProps}
        >
          {jurisdictions_list.map(jurisdiction_element => (
            <MenuItem key={jurisdiction_element} jurisdiction={jurisdiction_element}>
              <Checkbox checked={jurisdiction_element.indexOf(jurisdiction_element) > -1} />
              <ListItemText primary={jurisdiction_element} />
            </MenuItem>
          ))}
        </Select>
      </FormControl>
    </div>
  );
}


export default Dropdown;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-14 20:29:58

组件的简约版本

SelectableDropdown使用Set实例在内部跟踪所选的项,并且只通知父项(请记住,SelectableDropdown是一个不受控制的组件,您需要再添加几行代码才能使其成为受控组件)

代码语言:javascript
复制
function Searchbar(props) {
  
  function handleChange(ev) {
    props.onChange && props.onChange(ev.target.value);
  }
  
  return (
    <label className="Searchbar">
      Search 
      <input 
        type="text" 
        value={props.value}
        onChange={handleChange}
      />
    </label>
  )
}

function SelectableDropDown(props) {
  const [selectedOpts, setSelectedOpts] = React.useState(new Set());
  
  function handleChange(ev) {
    const value = ev.target.value;
    const checked = ev.target.checked;
    
    if (checked) {
      selectedOpts.add(value);
    } else {
      selectedOpts.delete(value);
    }
    
    setSelectedOpts(new Set(selectedOpts));
    props.onChange && props.onChange(Array.from(selectedOpts.values()));
  }
  
  return (
    <fielset className="SelectableDropDown">
      {props.options.map((opt) => (
        <label key={opt}>
          {opt} 
          <input 
            type="checkbox" 
            name="opts" 
            value={opt}
            onChange={handleChange}
          />
        </label>
      ))}
    </fielset>
  )
}

const OPTIONS = [
  'Jurisdiction 1',
  'Jurisdiction 2',
  'Jurisdiction 3',
  'Jurisdiction 4',
  'Jurisdiction 5',
];

function App() {
  const [query, setQuery] = React.useState('');
  const [selectedOptions, setSelectedOptions] = React.useState([]);
  
  function handleSubmit(ev) {
    ev.preventDefault();
    console.log('submitting');
    console.log(query);
    console.log(selectedOptions);
    console.log('submitting end');
  }
  
  function handleQueryChange(newQuery) {
    setQuery(newQuery);
  }
  
  function handleOptionsChange(newSelectedOptions) {
    setSelectedOptions(newSelectedOptions);
  }
  
  return (
    <form onSubmit={handleSubmit}>
      <Searchbar 
        value={query}
        onChange={handleQueryChange}
      />
      <div>
        <SelectableDropDown 
          options={OPTIONS}
          onChange={handleOptionsChange}
        />
      </div>
      <div>
        <button>Search</button>
      </div>
    </form>
  );
}


ReactDOM.render(
  <App />,
  document.getElementById('app')
);
代码语言:javascript
复制
.Searchbar,
.SelectableDropDown label {
  display:block;
}
代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script>
</head>
<body>
 <div id="app"></div>
</body>
</html>

票数 1
EN

Stack Overflow用户

发布于 2019-10-14 20:17:25

代码语言:javascript
复制
<Checkbox checked={jurisdiction_element.indexOf(jurisdiction_element) > -1} />

如果jurisdiction_element包含jurisdiction_element,则将选中复选框。该条件将始终计算为true,因此您的复选框将始终被选中。

它看起来像是您打算使用:

代码语言:javascript
复制
<Checkbox checked={value.indexOf(jurisdiction_element) > -1} />

此外,您不能通过执行<Select onChange={onChange, handleChange} />来设置两个回调函数。你需要选择一个或另一个。如果想同时使用这两种方法,那么让一个函数调用另一个函数,或者创建一个调用两者的新函数:

代码语言:javascript
复制
const handleChange = event => {
    onChange(event);
    console.log(value);
}

// or
<Select onChange={event => { onChange(event); handleChange(event); }} />
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58383280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档