我目前正在开发一个React应用(ES6),其中将列出许多食品。
每次点击产品时,单个产品计数(子状态)应每次增加1,这目前有效。
但是,使用母食品状态的数据也应增加总卡路里计数(父状态)。
示例:用户单击“抱子甘蓝”项目。 FoodItem计数每次点击将增加+1,但是在这种情况下,我还要求App类中的总卡路里计数(this.state.calorieCount)要增加28.1。
我是新来的反应者,因此在此方面的任何帮助将不胜感激。
// FoodCards.js
const FoodCards = [
{
id: 0,
name: 'Brussel Sprouts',
quantity: '1/2 cup',
calories: 28.1,
betacarotene: 0.363,
bilberry_fruit: 0,
curcumin: 0,
grapeseed: 0,
green_tea: 0,
lutein: 1,
lycopene: 0,
vitamin_a: 0.03,
vitamin_d: 0
},
...
];
export default FoodCards
// App.js
import React from 'react';
import './tailwind.output.css';
import './App.scss';
import FoodCards from './data/foods';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
foods: FoodCards,
calorieCount: 0,
vitaminACount: 0,
vitaminDCount: 0,
};
this.increment = this.increment.bind(this);
}
increment(calories, vitaminA, vitaminD) {
this.setState({
calorieCount: Math.round(this.state.calorieCount + calories),
vitaminACount: Math.round((this.state.vitaminACount + vitaminA) * 100) / 100,
vitaminDCount: Math.round((this.state.vitaminDCount + vitaminD) * 100) / 100
});
};
reset() {
this.setState({
calorieCount: 0,
vitaminACount: 0,
vitaminDCount: 0,
});
};
render() {
return (
<div className="App">
<header className="flex flex-wrap">
<div className="calories-total">
<span>Calories</span>
<span className="num">{this.state.calorieCount}</span>
</div>
<div className="vitamin-a-total">
<span>Vitamin A</span>
<span className="num">{this.state.vitaminACount}</span>
</div>
<div className="vitamin-d-total">
<span>Vitamin D</span>
<span className="num">{this.state.vitaminDCount}</span>
</div>
<div className="export-btn flex items-center justify-center">
Export Full Report
</div>
</header>
<main className="products-grid flex flex-wrap">
{this.state.foods.map((item, i) => {
return <FoodItem key={item.id} name={ item.name } calories={item.calories} />
})}
</main>
<footer>
<div className="reset" onClick={() => this.reset()}>Reset</div>
</footer>
</div>
);
}
}
export default App;
class FoodItem extends React.Component {
constructor(props) {
super(props);
this.state = {
clickCount: 0
};
}
handleClickIncrement() {
this.setState({
clickCount: this.state.clickCount + 1
});
};
render() {
return (
<div className="product" onClick={() => this.handleClickIncrement()}>
<p>{this.props.name} - {this.state.clickCount}</p>
<p>Calories: {this.props.calories}</p>
</div>
);
}
}
答案 0 :(得分:2)
您的FoodItem需要一个可以通知父项的功能。因此,在App中,您可以输入以下内容:
Input
也是在父母中
import React, { useState, useRef, forwardRef } from "react";
import Editor, { createEditorStateWithText } from "draft-js-plugins-editor";
import createEmojiPlugin from "draft-js-emoji-plugin";
import { TextField, makeStyles } from "@material-ui/core";
import { isObject } from "lodash";
import { findDOMNode } from "react-dom";
import classNames from 'classnames';
function InputWrapper(props) {
const { component: Component, inputRef, ...other } = props;
const ref = useRef();
React.useImperativeHandle(inputRef, () => ({
focus: () => {
findDOMNode(inputRef.current).focus();
},
}));
return <Component ref={ref} {...other} />;
}
const emojiPlugin = createEmojiPlugin();
const { EmojiSuggestions, EmojiSelect } = emojiPlugin;
const plugins = [emojiPlugin];
const text = `Cool, we can have all sorts of Emojis here. ?
?☃️?? aaaand maybe a few more here ?☀️? Quite fun!`;
const useStyles = makeStyles((theme) => ({
textField: {
width: "100%",
minHeight: 31,
tabSize: 8,
fontVariantLigatures: "none",
boxSizing: "content-box",
userSelect: "text",
whiteSpace: "pre-wrap",
},
}));
let DraftInput = (props, ref) => {
const {
InputProps,
InputLabelProps,
value,
handleEnterKeyPress,
onChange,
id,
...other
} = props;
const [editorState, setEditorState] = useState(
createEditorStateWithText(text)
);
const baseClasses = useStyles();
const handleChange = (state) => {
setEditorState(state);
// onChange(state);
};
const propClass =
isObject(InputProps) && InputProps.hasOwnProperty("className")
? InputProps.className
: false;
const classes = classNames([baseClasses, propClass, "emoji-input"]);
return (
<div>
<TextField
inputRef={ref}
autoFocus={true}
value={value}
InputProps={{
inputComponent: InputWrapper,
inputProps: {
component: Editor,
onChange: handleChange,
editorState,
},
...InputProps,
}}
InputLabelProps={{
...InputLabelProps,
}}
{...InputProps}
{...other}
/>
</div>
);
};
DraftInput = forwardRef(DraftInput);
export default DraftInput;
<FoodItem
updateParent={this.updateFromItem.bind(this)}
// other props
/>
函数位于父组件中,并且通过 updateFromItem(calories) {
this.increment(calories, 0, 0);
}
对其进行了范围调整,但是您从子项(FoodItem)传播更改并从那里调用它:
updateFromItem