我正在尝试将以下组件转换为功能组件,以便可以使用react context API?
我要转换的组件的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;
这就是我所做的
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;
在我的IDE或网页上没有错误消息,但是当我单击切换模式的按钮时,我得到了一个空白的白色屏幕,没有错误消息。
答案 0 :(得分:1)
useState
挂钩返回状态变量的当前值和用于更改状态变量的函数。就您而言
const [selected, setSelected] = useState('small')
您将在以前使用selected
的任何地方使用this.state.selected
,并在以前曾经使用setSelected()
的任何地方使用this.setState({ selected })
。因此,代码中的第一个问题是读取状态值时滥用setter函数。
要将函数传递给组件时,必须确保传递函数而不是调用函数。例如
onChange={toggleHandler("large")}
将立即获取返回值toggleHandler("large")
,并尝试在值更改时调用它。您对toggleHandler
的定义不会返回任何内容,因此,当您更改单选按钮时,实际上只是在尝试将undefined
作为函数来调用,这当然是行不通的。
此外,输入的onChange
处理程序还会传递综合事件。您应该使用它来提取按下哪个单选按钮。
尝试这样的事情:
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;
供以后参考,浏览器的Javascript控制台(通常在开发人员工具部分)中也会出现错误。您可以在那里检查错误。我的猜测是,试图将undefined
作为函数进行调用以及由于setSelected
调用而导致的渲染循环的某种组合是造成您的问题的原因。
答案 1 :(得分:1)
我在您的代码中发现的几个错误,看看这是否会改变
setSelected({toggle: Selected});
相反,您应该为其赋予“已选择”的值
setSelected(Selected);
if(setSelected(Selected==='small'))
错了,您只需要检查
if(Selected==='small')
4。最后进入OnChange
onChange={toggleHandler("small")}
您可以只调用setSelected
onChange={() => setSelected("small")}