[英]How can I convert a state component that has a toggle function to a stateless one in reactjs?
I am trying to convert the following component to a functional one so I could use the react context API?我正在尝试将以下组件转换为功能组件,以便可以使用反应上下文 API?
The JSX code for the component I want to convert我要转换的组件的 JSX 代码
class pizzaModal extends Component {
state = {
selected: "small",
showModal: true,
selectedOrder: null
}
toggleHandler = (size)=> ()=>{
this.setState({
toggle: size
});
}
addToOrders = (p)=>{
this.setState(prevState=>({
selectedOrder: p
}))
}
render (){
let attachedClasses = [styles.ImageContainer]
if(this.state.toggle==='small'){
attachedClasses = [styles.ImageContainer, styles.Small]
}
if(this.state.toggle==="medium"){
attachedClasses = [styles.ImageContainer, styles.Medium]
}
if(this.state.toggle==="large"){
attachedClasses=[styles.ImageContainer, styles.Large]
}
return (
<Aux>
<div className={styles.Pizzamodal}>
<div className={styles.ModalContainer}>
<div className={attachedClasses.join(' ')}>
<img src={this.props.image} alt="pizzapicture"/>
</div>
<div className={styles.DetailsContainer}>
<div>
<div className={styles.TextDetails}>
<h1>{this.props.name}</h1>
<p>{this.props.ingredients}</p>
</div>
<div>
<div className={styles.Form}>
<form className={styles.switchButton}>
<input type="radio" name="pizza" id="small" value="small" onChange={this.toggleHandler("small")}
checked={this.state.toggle==="small"}/>
<label for="small">Small</label>
<input type="radio" name="pizza" id="medium" value="medium" onChange={this.toggleHandler("medium")}
checked={this.state.toggle==="medium"}/>
<label for="medium">Medium</label>
<input type="radio" name="pizza" id="large" value="large" onChange={this.toggleHandler("large")}
checked={this.state.toggle==="large"}/>
<label for="large">Large</label>
</form>
</div>
<div className={styles.orderButton}>
<button onClick={this.props.addToOrders}>Add to basket for ₦{this.props.price}</button>
</div>
</div>
</div>
</div>
<div className={styles.Navbar} onClick={this.props.clicked}>
<div></div>
<div></div>
</div>
</div>
</div>
</Aux>
)
}
}
export default pizzaModal;
This is what I have done这就是我所做的
const PizzaModal= (props) => {
const [Selected, setSelected] = useState('small')
const toggleHandler = (size)=>{
setSelected({
toggle: Selected
});
}
/*const [orders, setOrders] = useContext([CartContext]);
const addToOrders=()=>{
const pizza = {name: this.props.name, ingredients: this.props.ingredients, image: this.props.image, price: this.props.price}
setOrders([...orders, pizza])
}*/
let attachedClasses = [styles.ImageContainer]
if(setSelected(Selected==='small')){
attachedClasses = [styles.ImageContainer, styles.Small]
}
if(setSelected(Selected==="medium")){
attachedClasses = [styles.ImageContainer, styles.Medium]
}
if(setSelected(Selected==="large")){
attachedClasses=[styles.ImageContainer, styles.Large]
}
return (
<Aux>
<div className={styles.Pizzamodal}>
<div className={styles.ModalContainer}>
<div className={attachedClasses.join(' ')}>
<img src={props.image} alt="pizzapicture"/>
</div>
<div className={styles.DetailsContainer}>
<div>
<div className={styles.TextDetails}>
<h1>{props.name}</h1>
<p>{props.ingredients}</p>
</div>
<div>
<div className={styles.Form}>
<form className={styles.switchButton}>
<input type="radio" name="pizza" id="small" value="small" onChange={toggleHandler("small")}
checked={setSelected(Selected==='small')}/>
<label for="small">Small</label>
<input type="radio" name="pizza" id="medium" value="medium" onChange={toggleHandler("medium")}
checked={setSelected(Selected==='medium')}/>
<label for="medium">Medium</label>
<input type="radio" name="pizza" id="large" value="large" onChange={toggleHandler("large")}
checked={setSelected(Selected==='large')}/>
<label for="large">Large</label>
</form>
</div>
<div className={styles.orderButton}>
<button >Add to basket for ₦{props.price}</button>
</div>
</div>
</div>
</div>
<div className={styles.Navbar} onClick={props.clicked}>
<div></div>
<div></div>
</div>
</div>
</div>
</Aux>
)
}
export default PizzaModal;
I have no error messages on my IDE or on the webpage but when I click on the button that toggles the modal on I get a blank white screen with no error messages.我的 IDE 或网页上没有错误消息,但是当我单击切换模式的按钮时,我得到一个没有错误消息的空白屏幕。
couple of mistakes i spotted in your code see if this changes anything我在您的代码中发现了几个错误,看看这是否会改变任何东西
setSelected({toggle: Selected});
instead u should give it the value of Selected相反,你应该给它 Selected 的值
setSelected(Selected);
if(setSelected(Selected==='small'))
is wrong u just have to check错了你只需要检查
if(Selected==='small')
4.And finally in OnChange 4.最后在 OnChange
onChange={toggleHandler("small")}
you can just call setSelected你可以调用 setSelected
onChange={() => setSelected("small")}
The useState
hook returns the current value of the state variable and a function to change it. useState
挂钩返回 state 变量的当前值和 function 以更改它。 In your case with在你的情况下
const [selected, setSelected] = useState('small')
you would use selected
anywhere you previously would have used this.state.selected
and use setSelected()
anywhere you previously would have used this.setState({ selected })
.您可以在以前使用过
this.state.selected
的任何地方使用selected
,并在以前使用过this.setState({ selected })
的任何地方使用setSelected()
) 。 So the first issue in your code is the misuse of the setter function when reading the state value.因此,代码中的第一个问题是在读取 state 值时滥用设置器 function。
When you want to pass a function to a component, you have to make sure you're passing the function and not a call to the function.当您想将 function 传递给组件时,您必须确保传递的是 function 而不是对 function 的调用。 For example
例如
onChange={toggleHandler("large")}
will immediately get the return value of toggleHandler("large")
and try to call that when the value changes.将立即获得
toggleHandler("large")
的返回值,并在值更改时尝试调用它。 Your definition of toggleHandler
doesn't return anything, so when you change your radio buttons, you're actually just trying to call undefined
as a function, which of course doesn't work.您对
toggleHandler
的定义没有返回任何内容,因此当您更改单选按钮时,您实际上只是试图将undefined
调用为 function,这当然不起作用。
Also, the onChange
handler of an input passes a synthetic event.此外,输入的
onChange
处理程序传递一个合成事件。 You should use that to extract which radio button was pressed.您应该使用它来提取按下了哪个单选按钮。
Try something like this:尝试这样的事情:
const PizzaModal = (props) => {
const [selected, setSelected] = useState('small')
const toggleHandler = (event) => {
setSelected(event.target.value);
}
let attachedClasses = [styles.ImageContainer]
if (selected === 'small')) {
attachedClasses = [styles.ImageContainer, styles.Small]
}
if (selected === "medium")) {
attachedClasses = [styles.ImageContainer, styles.Medium]
}
if (selected === "large")) {
attachedClasses=[styles.ImageContainer, styles.Large]
}
return (
<Aux>
<div className={styles.Pizzamodal}>
<div className={styles.ModalContainer}>
<div className={attachedClasses.join(' ')}>
<img src={props.image} alt="pizzapicture"/>
</div>
<div className={styles.DetailsContainer}>
<div>
<div className={styles.TextDetails}>
<h1>{props.name}</h1>
<p>{props.ingredients}</p>
</div>
<div>
<div className={styles.Form}>
<form className={styles.switchButton}>
<input type="radio" name="pizza" id="small" value="small" onChange={toggleHandler} checked={selected === 'small'}/>
<label for="small">Small</label>
<input type="radio" name="pizza" id="medium" value="medium" onChange={toggleHandler} checked={selected === 'medium'}/>
<label for="medium">Medium</label>
<input type="radio" name="pizza" id="large" value="large" onChange={toggleHandler} checked={selected === 'large'}/>
<label for="large">Large</label>
</form>
</div>
<div className={styles.orderButton}>
<button >Add to basket for ₦{props.price}</button>
</div>
</div>
</div>
</div>
<div className={styles.Navbar} onClick={props.clicked}>
<div></div>
<div></div>
</div>
</div>
</div>
</Aux>
)
}
export default PizzaModal;
For future reference, errors also come through in the browser's Javascript console (usually in the developer tools section).为了将来参考,浏览器的 Javascript 控制台(通常在开发人员工具部分)中也会出现错误。 You can check there for errors.
你可以在那里检查错误。 My guess is that some combination of trying to call
undefined
as a function and a render loop due to the setSelected
calls is what was causing your issue.我的猜测是,由于
setSelected
调用而尝试将undefined
调用为 function 和渲染循环的某种组合是导致您的问题的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.