我试图将一个组件包装到另一个组件中,并从该“一个”组件中调用一个函数。
<Parent>
<Child1>
<button
onClick={
//toggleSomething
console.log("Run function `toggleSomething` from parent")
}
>
Change state 1
</button>
</Child1>
<Child2>
<button
onClick={
//toggleSomething
console.log("Run function `toggleSomething` from parent")
}
>
Change state 2
</button>
</Child2>
</Parent>
在父组件中,我有:
class Parent extends React.Component {
state = {
something: false
};
toggleSomething = () => {
this.setState({
something: true
});
};
render() {
return <div className="parentClasses">{this.props.children}</div>;
}
}
这里是游乐场:https://codesandbox.io/s/1ykllwnyq3
有解决方案吗?
答案 0 :(得分:1)
承担这些组件的责任:
Parent
:照顾国家。Child1
和Child2
:通用UI容器。App
:关注Parent
的状态呈现方式。这可以使用render props技术来完成。
在下面的示例中,没有将元素作为子元素传递给<Parent>
,a function is passed in instead。
class App extends React.Component {
render() {
return (
<div>
<Parent>
{toggle => (
<React.Fragment>
<Child1>
<button onClick={toggle}>Change state 1</button>
</Child1>
<Child2>
<button onClick={toggle}>Change state 2</button>
</Child2>
</React.Fragment>
)}
</Parent>
</div>
);
}
}
class Parent extends React.Component {
state = {
something: false
};
toggleSomething = () => {
this.setState({
something: true
});
};
render() {
return (
<div className="parentClasses">
{this.state.something.toString()}
{this.props.children(this.toggleSomething)}
</div>
);
}
}
const Child1 = props => {
return <div class="someClasses">{props.children}</div>;
};
const Child2 = props => {
return <div class="someOtherClasses">{props.children}</div>;
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, 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>
答案 1 :(得分:0)
class App extends React.Component {
render() {
return (
<div>
<Parent>
<Child1 />
<Child2 />
</Parent>
</div>
);
}
}
class Parent extends React.Component {
state = {
something: false
};
toggleSomething = () => {
console.log("now toggling !!");
this.setState({
something: true
});
};
render() {
const reactChildren = React.Children.toArray(this.props.children);
const childrenWithProps = reactChildren.map(element =>
React.cloneElement(element, {
toggleSomething: this.toggleSomething
})
);
return <div className="parentClasses">{childrenWithProps}</div>;
}
}
const Child1 = props => {
return (
<div class="someClasses">
<button
onClick={
//toggleSomething
() => {
props.toggleSomething();
console.log("Run function `toggleSomething` from parent");
}
}
>
Change state 1
</button>
</div>
);
};
const Child2 = props => {
return (
<div class="someOtherClasses">
<button
onClick={() => {
debugger;
props.toggleSomething();
console.log("Run function `toggleSomething` from button 2");
}}
>
Change state 2
</button>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>.
现在,可以根据以下方式呈现Child 2和Child1的内容 道具让我们明天说,您想要给Child 2视图其他的东西。 您可以像这样更改子组件。
const Child2 = props => {
const { RenderView, toggleSomething } = props
//renderView is your view Component(stateless/statefull)
return (
<div class="someOtherClasses">
{<RenderView toggleSomething={toggleSomething} />}
</div>
);
};
这种方法怎么样?。
答案 2 :(得分:0)
您需要传递函数,并从道具中访问它。 克隆元素可让您将道具添加到所有子项。
import React from "react";
import ReactDOM from "react-dom";
const Child1 = props => {
return <button onClick={props.handler}>test</button>;
};
class Parent extends React.Component {
state = {
something: "nope"
};
toggleSomething = () => {
this.setState({
something: "yes"
});
};
render() {
const childrenWithProps = React.Children.map(
this.props.children, child =>
React.cloneElement(
child, { handler: this.toggleSomething }
)
);
return <div className="parentClasses">
{this.state.something}
{childrenWithProps}
</div>;
}
}
const App = () =>
<Parent>
<Child1/>
</Parent>
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);