我正在尝试创建一个组件,在该组件中将传递十二个嵌套值以及一些父项。
在此组件中,我有两个按钮,每个按钮都有一个onClick事件,当我按下该按钮时,我试图将其嵌套,以便将嵌套prop的值传递给函数并进行更改,并在视图中进行更新。
在此示例中,我仅传递someChildProp,这是一个示例道具:
List.defaultProps = {
someChildProp: {
field1: 1.4,
field2: 1.2,
field3: 1.6,
field4: 1.1
}
};
当您按下任一按钮时:
<a className="unit-selected" onClick={handleUnitClick('unit1')}>
Unit 1
</a>
<span>/</span>
<a onClick={handleUnitClick('unit2')}>
Unit 2
</a>
这将运行handleUnitClick,它将检查传递的值,然后在我设置所有道具的位置运行该函数。
const handeUnitClick = (type) => {
if (type === 'unit1') {
convertProps();
}
}
const convertProps = () => {
Object.keys(someChildProp).map((item, index) => {
// set new value with convertUnit(number)
// concat to new object?
// set state again?
})
}
const convertUnit = (number) => {
return number + 5;
}
因此,设置新状态在.map中看起来像这样。
someChildProp: {
key[index]: convertUnit(value)
}
我不确定该怎么做,如何映射每个对象,更改值,设置整个ChildProp的状态?
所以我被困在这一点上:
const convertProps = () => {
Object.keys(someChildProp).map((item, index) => {
// set new value with convertUnit(number)
// concat to new object?
// set state again?
})
}
我该怎么做?
以下是全部代码:https://codesandbox.io/embed/competent-firefly-soyv4
答案 0 :(得分:1)
缺少一些细节,但这大概就是您想要的能够在两个单位之间转换的东西吗?
一些注意事项:
button
(而不是锚点:a
)() => this. handleUnitClick('unit1')
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
someChildProp: {
field1: 1.4,
field2: 1.2,
field3: 1.6,
field4: 1.1
}
};
}
handleUnitClick = type => {
if (type === "unit1") {
this.convertProps(this.convertUnitOne);
} else if (type === "unit2") {
this.convertProps(this.convertUnitTwo);
}
};
convertProps = convertFn => {
const someChildProp = {};
Object.keys(this.state.someChildProp).forEach(item => {
someChildProp[item] = convertFn(this.state.someChildProp[item]);
});
this.setState({ someChildProp });
};
convertUnitOne = number => {
return number + 5;
};
convertUnitTwo = number => {
return number / 5;
};
render() {
return (
<React.Fragment>
<button onClick={() => this.handleUnitClick("unit1")}>Unit 1</button>
<button onClick={() => this.handleUnitClick("unit2")}>Unit 2</button>
<ul>
<li>{this.state.someChildProp.field1}</li>
<li>{this.state.someChildProp.field2}</li>
<li>{this.state.someChildProp.field3}</li>
<li>{this.state.someChildProp.field4}</li>
</ul>
</React.Fragment>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
或者,使用挂钩代替您的Codesandbox。
最大的问题是您正在使用无法更改的默认道具(使用当前设置)。似乎更合适的方法是状态,或使用带有对象默认值(而不是默认道具)的钩子useState
。
const List = ({ someChildProp }) => {
const [values, setValues] = React.useState({
field1: 1.4,
field2: 1.2,
field3: 1.6,
field4: 1.1
})
const handleUnitClick = type => {
if (type === "unit1") {
convertProps();
}
};
const convertProps = () => {
const newValues = {};
Object.keys(values).forEach((key) => {
newValues[key] = convertUnit(values[key])
});
setValues(newValues)
};
const convertUnit = number => {
return number + 5;
};
return (
<div className="modal-items">
<header className="modal">
<h3>List</h3>
</header>
<div className="unit-options">
<a className="unit-selected" onClick={() => handleUnitClick("unit1")}>
Unit 1
</a>
<span>/</span>
<a onClick={() => handleUnitClick("unit2")}>Unit 2</a>
</div>
<div className="items-table-container">
<div className="items-table items-performance">
<h4 className="items-title">Performance</h4>
<ul className="items">
<li className="items-spec">
<div className="items-spec-label">Field 1</div>
<div className="items-spec-value">{values.field1}</div>
</li>
<li className="items-spec">
<div className="items-spec-label">Field 2</div>
<div className="items-spec-value">{values.field2}</div>
</li>
<li className="items-spec">
<div className="items-spec-label">Field 3</div>
<div className="items-spec-value">{values.field3}</div>
</li>
<li className="items-spec">
<div className="items-spec-label">Field 4</div>
<div className="items-spec-value">{values.field4}</div>
</li>
</ul>
</div>
</div>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<List />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>