您将获得不可控制的子组件。 父组件存储计数器数量,并渲染该数量的子组件。它有两个按钮,“添加计数器”和“增加所有计数器”。
不允许您编辑子组件。
实施 IncreaseCounters,以便它增加所有子项的计数器 呈现的组件。
incrementCounters =()=> { // TODO:实作 };
export class ChildCounter extends React.Component{
state = {
counter: 0
};
increment = () => {
this.setState(({ counter }) => ({
counter: counter + 1
}));
};
render() {
return (
<div>
Counter: {this.state.counter}
<button onClick={this.increment}>+</button>
</div>
);
}
}
import {ChildCounter} from "./Child";
class App extends React.Component {
state = {counters:1}
addCounter = () => {
let counterRn = this.state.counters + 1;
this.setState({counters:counterRn})
};
incrementAll = () => {
}
render() {
return (
<div>
{ new Array(this.state.counters).fill(0).map((_, index) => {
return <ChildCounter key={index} />;
})
}
<br/>
<button style={{marginRight:10}} onClick={this.addCounter}>Add Counter</button>
<button onClick={this.incrementAll}>Increment all counters</button>
</div>
)
}
}
答案 0 :(得分:0)
首先,我不知道为什么你不想用状态来做,我认为这会好得多 通过使用一个计数器值数组,然后一次全部增加它们,并将您的子组件作为控制器组件。
对于裁判,我无法提出一个好的解决方案(不确定)。
因此,我在这里传递了代码,然后做的是,我使用了一个名为 function addItems() {
var newItems = [createNewRowData(), createNewRowData(), createNewRowData()];
var res = gridOptions.api.applyTransaction({ add: newItems });
printResult(res);
}
function printResult(res) {
console.log('---------------------------------------');
if (res.add) {
res.add.forEach(function(rowNode) {
console.log('Added Row Node', rowNode);
});
}
if (res.remove) {
res.remove.forEach(function(rowNode) {
console.log('Removed Row Node', rowNode);
});
}
if (res.update) {
res.update.forEach(function(rowNode) {
console.log('Updated Row Node', rowNode);
});
}
}
的react钩子,使您的子组件使用ref并公开了内部useImperativeHandle
方法。
然后我在您的父组件中添加了一组引用。
因此,当用户单击“全部增量”时,基本上可以遍历引用并调用内部增量方法。
我仍然不确定实现引用数组的正确方法,但是我认为应该这样做。
而且我已经用钩子编写了它,以使其更易于理解。
increment
https://codesandbox.io/s/trusting-neumann-37e2q?file=/src/App.js:0-1327
答案 1 :(得分:0)
这是在技术上可能的,无需更改父级的ref即可更改子级,并且让父级每次使用ref来访问子级上的increment
方法incrementAll
被称为:
childCounterChildren = [];
incrementAll = () => {
for (const counter of this.childCounterChildren) {
counter.increment();
}
}
<ChildCounter
key={index}
ref={(childCounter) => { if (childCounter) { this.childCounterChildren.push(childCounter); }}}
/>;
class ChildCounter extends React.Component {
state = {
counter: 0
};
increment = () => {
this.setState(({ counter }) => ({
counter: counter + 1
}));
};
render() {
return (
<div>
Counter: {this.state.counter}
<button onClick={this.increment}>+</button>
</div>
);
}
}
class App extends React.Component {
state = { counters: 1 }
childCounterChildren = [];
addCounter = () => {
let counterRn = this.state.counters + 1;
this.setState({ counters: counterRn })
};
incrementAll = () => {
for (const counter of this.childCounterChildren) {
counter.increment();
}
}
componentWillUpdate() {
this.childCounterChildren.length = 0;
}
render() {
return (
<div>
{new Array(this.state.counters).fill(0).map((_, index) => {
return <ChildCounter
key={index}
ref={(childCounter) => { if (childCounter) { this.childCounterChildren.push(childCounter); }}}
/>;
})
}
<br />
<button style={{ marginRight: 10 }} onClick={this.addCounter}>Add Counter</button>
<button onClick={this.incrementAll}>Increment all counters</button>
</div>
)
}
}
ReactDOM.render(<App />, document.querySelector('.react'));
<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 class='react'></div>
但这很奇怪。对于实际问题,我建议使用lifting state up。