反应复选框未正确呈现
react check box not rendering correctly
我正在尝试创建一个代表图块的 React 组件。
这个组件只是一个 div,由一个标签和一个复选框组成。
我遇到的问题是,我可以单击组件上的任何位置,并且状态会像往常一样发生变化(例如:通过单击组件,我可以选中或取消选中复选框)。但是当我点击复选框时没有任何反应。
这是我新创建的组件代码:
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(()=>{
console.log(selected)
},[selected])
return (
<>
<div className="tile" onClick={ev=>setSelected(curr=>!curr)}>
<label>{title}</label>
<input
type="checkbox"
checked={!!selected}
onChange={ev=>{setSelected(curr=>!curr)}}
></input>
</div>
</>
);
};
我在 App.js 中使用它:
return (
<Container>
<Row>
<Col md={4}>
<Tile title="USA"></Tile>
<Tile title="MOROCCO"></Tile>
<Tile title="FRANCE"></Tile>
</Col>
<Col md={8}>
<h1>Hello</h1>
</Col>
</Row>
</Container>
最后是我的 css :
body {
padding-top: 20px;
font-family: "Poppins", sans-serif;
background-color: cornsilk;
}
.tile {
position: relative;
display: block;
width: 100%;
min-height: fit-content;
background: bisque;
padding: 8px;
margin: 1px;
}
.tile input[type="checkbox"] {
position: absolute;
top: 50%;
right: 0%;
transform: translate(-50%, -50%);
}
编辑:在标签上使用 htmlFor 修复的问题是标签是可点击的,复选框是可点击的,但它们之间的 space 不是。我希望整个组件都可以点击
将 htmlFor prop 添加到标签并将 id 添加到与该 htmlFor 值匹配的输入。
在您的情况下,Tile 组件将是:
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(()=>{
console.log(selected)
},[selected])
return (
<>
<div className="tile" onClick={ev=>setSelected(curr=>!curr)}>
<label htmlFor={title}>{title}</label>
<input
id={title}
type="checkbox"
checked={!!selected}
onChange={ev=>{setSelected(curr=>!curr)}}
></input>
</div>
</>
);
};
您的 div
上不需要 onClick
。
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(() => {
console.log(selected);
}, [selected]);
return (
<>
<div className="tile" onClick={() => setSelected((curr) => !curr)}>
<label htmlFor={title}>{title}</label>
<input
id={title}
type="checkbox"
checked={!!selected}
onChange={(ev) => {}}
/>
</div>
</>
);
};
我做了一个代码沙箱来测试:https://codesandbox.io/s/optimistic-tharp-czlgp?file=/src/App.js:124-601
当你点击复选框时,你的点击事件被 div 和 div 中的复选框传播和处理,这导致状态被切换两次并最终具有相同的状态值和以前一样。
您需要删除其中一个 onClicks,具体取决于您希望可点击的内容(整个 div 或仅带有标签的复选框)。
可点击div:
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(() => {
console.log(selected)
}, [selected])
return (
<>
<div className="tile" onClick={() => setSelected(curr => !curr)}>
<label>{title}</label>
<input
type="checkbox"
checked={!!selected}
/>
</div>
</>
);
};
可点击的复选框和标签:
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(() => {
console.log(selected)
}, [selected])
return (
<>
<div className="tile">
<label htmlFor="title">{title}</label>
<input
id="title"
type="checkbox"
checked={!!selected}
onChange={() => setSelected(curr => !curr)}
/>
</div>
</>
);
};
我正在尝试创建一个代表图块的 React 组件。
这个组件只是一个 div,由一个标签和一个复选框组成。
我遇到的问题是,我可以单击组件上的任何位置,并且状态会像往常一样发生变化(例如:通过单击组件,我可以选中或取消选中复选框)。但是当我点击复选框时没有任何反应。
这是我新创建的组件代码:
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(()=>{
console.log(selected)
},[selected])
return (
<>
<div className="tile" onClick={ev=>setSelected(curr=>!curr)}>
<label>{title}</label>
<input
type="checkbox"
checked={!!selected}
onChange={ev=>{setSelected(curr=>!curr)}}
></input>
</div>
</>
);
};
我在 App.js 中使用它:
return (
<Container>
<Row>
<Col md={4}>
<Tile title="USA"></Tile>
<Tile title="MOROCCO"></Tile>
<Tile title="FRANCE"></Tile>
</Col>
<Col md={8}>
<h1>Hello</h1>
</Col>
</Row>
</Container>
最后是我的 css :
body {
padding-top: 20px;
font-family: "Poppins", sans-serif;
background-color: cornsilk;
}
.tile {
position: relative;
display: block;
width: 100%;
min-height: fit-content;
background: bisque;
padding: 8px;
margin: 1px;
}
.tile input[type="checkbox"] {
position: absolute;
top: 50%;
right: 0%;
transform: translate(-50%, -50%);
}
编辑:在标签上使用 htmlFor 修复的问题是标签是可点击的,复选框是可点击的,但它们之间的 space 不是。我希望整个组件都可以点击
将 htmlFor prop 添加到标签并将 id 添加到与该 htmlFor 值匹配的输入。
在您的情况下,Tile 组件将是:
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(()=>{
console.log(selected)
},[selected])
return (
<>
<div className="tile" onClick={ev=>setSelected(curr=>!curr)}>
<label htmlFor={title}>{title}</label>
<input
id={title}
type="checkbox"
checked={!!selected}
onChange={ev=>{setSelected(curr=>!curr)}}
></input>
</div>
</>
);
};
您的 div
上不需要 onClick
。
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(() => {
console.log(selected);
}, [selected]);
return (
<>
<div className="tile" onClick={() => setSelected((curr) => !curr)}>
<label htmlFor={title}>{title}</label>
<input
id={title}
type="checkbox"
checked={!!selected}
onChange={(ev) => {}}
/>
</div>
</>
);
};
我做了一个代码沙箱来测试:https://codesandbox.io/s/optimistic-tharp-czlgp?file=/src/App.js:124-601
当你点击复选框时,你的点击事件被 div 和 div 中的复选框传播和处理,这导致状态被切换两次并最终具有相同的状态值和以前一样。
您需要删除其中一个 onClicks,具体取决于您希望可点击的内容(整个 div 或仅带有标签的复选框)。
可点击div:
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(() => {
console.log(selected)
}, [selected])
return (
<>
<div className="tile" onClick={() => setSelected(curr => !curr)}>
<label>{title}</label>
<input
type="checkbox"
checked={!!selected}
/>
</div>
</>
);
};
可点击的复选框和标签:
const Tile = ({ title }) => {
const [selected, setSelected] = useState(false);
useEffect(() => {
console.log(selected)
}, [selected])
return (
<>
<div className="tile">
<label htmlFor="title">{title}</label>
<input
id="title"
type="checkbox"
checked={!!selected}
onChange={() => setSelected(curr => !curr)}
/>
</div>
</>
);
};