React 钩子在事件处理程序中不起作用
React hook is not working from event handler
反应版本:16.8.2
const { useState } = React;
const Dropdown = ({
options,
onClick,
selected,
}) => {
const [showDropDown, setShowDropDown] = useState(false);
function toggleDropDown() {
setShowDropDown(v => !v);
}
function createOption(o) {
return (
<div
key={o}
className='drop-down__option'
onClick={() => {
onClick(o);
toggleDropDown();
// The following isn't working either
// setShowDropDown(false);
}}
>
{o}
</div>
);
}
return (
<div
onClick={toggleDropDown}
className='drop-down'
>
<div>{selected}</div>
{showDropDown && (
<div className='drop-down__list'>
{options.map(createOption)}
</div>
)}
</div>
);
};
const App = () => {
const [selected, setSelected] = useState(0);
return (
<Dropdown
selected={selected}
options={[0,1,2,3]}
onClick={v=>{setSelected(v)}}
/>
);
}
ReactDOM.render(
<App />,
document.getElementById('root'),
);
所以,这是一个简单的 Dropdown
,当您单击容器时,它会切换 Dropdown
。
But the problem here is, after clicking one of the options, the option has been updated, but the Dropdown
is not been closed.
所以在下面的代码中出现toggleDropDown();
没有效果
onClick={() => {
onClick(o);
toggleDropDown();
// The following isn't working either
// setShowDropDown(false);
}}
可在此处找到重现示例:https://codepen.io/vensa-albertgao/pen/ommGZe
我错过了什么?
将 toggleDropDown
函数更改为
function toggleDropDown() {
setShowDropDown(!showDropDown);
}
分叉示例
你的代码中的问题是 click
even on dropdown
options 被传播到你再次调用 toggleDropdown
onClick 的父级,因此切换发生了两次使其不明显发生。您只需要在选项上停止传播 click
const { useState } = React;
const Dropdown = ({
options,
onClick,
selected,
}) => {
const [showDropDown, setShowDropDown] = useState(false);
function toggleDropDown() {
console.log('called');
setShowDropDown(v => { console.log(v); return !v});
}
function createOption(option) {
return (
<div
key={option}
className='drop-down__option'
onClick={e => {
e.stopPropagation();
onClick(option);
toggleDropDown();
}}
>
{option}
</div>
);
}
return (
<div
onClick={toggleDropDown}
className='drop-down'
>
<div>{selected}</div>
{showDropDown && (
<div className='drop-down__list'>
{options.map(createOption)}
</div>
)}
</div>
);
};
const App = () => {
const [selected, setSelected] = useState(0);
return (
<Dropdown
selected={selected}
options={[0,1,2,3]}
onClick={v=>{setSelected(v)}}
/>
);
}
ReactDOM.render(
<App />,
document.getElementById('root'),
);
反应版本:16.8.2
const { useState } = React;
const Dropdown = ({
options,
onClick,
selected,
}) => {
const [showDropDown, setShowDropDown] = useState(false);
function toggleDropDown() {
setShowDropDown(v => !v);
}
function createOption(o) {
return (
<div
key={o}
className='drop-down__option'
onClick={() => {
onClick(o);
toggleDropDown();
// The following isn't working either
// setShowDropDown(false);
}}
>
{o}
</div>
);
}
return (
<div
onClick={toggleDropDown}
className='drop-down'
>
<div>{selected}</div>
{showDropDown && (
<div className='drop-down__list'>
{options.map(createOption)}
</div>
)}
</div>
);
};
const App = () => {
const [selected, setSelected] = useState(0);
return (
<Dropdown
selected={selected}
options={[0,1,2,3]}
onClick={v=>{setSelected(v)}}
/>
);
}
ReactDOM.render(
<App />,
document.getElementById('root'),
);
所以,这是一个简单的 Dropdown
,当您单击容器时,它会切换 Dropdown
。
But the problem here is, after clicking one of the options, the option has been updated, but the
Dropdown
is not been closed.
所以在下面的代码中出现toggleDropDown();
没有效果
onClick={() => {
onClick(o);
toggleDropDown();
// The following isn't working either
// setShowDropDown(false);
}}
可在此处找到重现示例:https://codepen.io/vensa-albertgao/pen/ommGZe
我错过了什么?
将 toggleDropDown
函数更改为
function toggleDropDown() {
setShowDropDown(!showDropDown);
}
分叉示例
你的代码中的问题是 click
even on dropdown
options 被传播到你再次调用 toggleDropdown
onClick 的父级,因此切换发生了两次使其不明显发生。您只需要在选项上停止传播 click
const { useState } = React;
const Dropdown = ({
options,
onClick,
selected,
}) => {
const [showDropDown, setShowDropDown] = useState(false);
function toggleDropDown() {
console.log('called');
setShowDropDown(v => { console.log(v); return !v});
}
function createOption(option) {
return (
<div
key={option}
className='drop-down__option'
onClick={e => {
e.stopPropagation();
onClick(option);
toggleDropDown();
}}
>
{option}
</div>
);
}
return (
<div
onClick={toggleDropDown}
className='drop-down'
>
<div>{selected}</div>
{showDropDown && (
<div className='drop-down__list'>
{options.map(createOption)}
</div>
)}
</div>
);
};
const App = () => {
const [selected, setSelected] = useState(0);
return (
<Dropdown
selected={selected}
options={[0,1,2,3]}
onClick={v=>{setSelected(v)}}
/>
);
}
ReactDOM.render(
<App />,
document.getElementById('root'),
);