Javascript 如何将道具传递给{this.props.children}
我试图找到合适的方法来定义一些可以通用方式使用的组件:Javascript 如何将道具传递给{this.props.children},javascript,reactjs,react-jsx,Javascript,Reactjs,React Jsx,我试图找到合适的方法来定义一些可以通用方式使用的组件: <Parent> <Child value="1"> <Child value="2"> </Parent> 父组件和子组件之间的渲染有一个逻辑,当然,您可以想象和作为该逻辑的一个示例 就问题而言,这是一个虚拟实现: var Parent = React.createClass({ doSomething: function(value) { }, render: f
<Parent>
<Child value="1">
<Child value="2">
</Parent>
父组件和子组件之间的渲染有一个逻辑,当然,您可以想象
和
作为该逻辑的一个示例
就问题而言,这是一个虚拟实现:
var Parent = React.createClass({
doSomething: function(value) {
},
render: function() {
return (<div>{this.props.children}</div>);
}
});
var Child = React.createClass({
onClick: function() {
this.props.doSomething(this.props.value); // doSomething is undefined
},
render: function() {
return (<div onClick={this.onClick}></div>);
}
});
var Parent=React.createClass({
doSomething:函数(值){
},
render:function(){
返回({this.props.children});
}
});
var Child=React.createClass({
onClick:function(){
this.props.doSomething(this.props.value);//doSomething未定义
},
render:function(){
返回();
}
});
问题是,每当您使用
{this.props.children}
定义包装器组件时,如何将某些属性传递给它的所有子组件?这是您所需要的吗
var Parent = React.createClass({
doSomething: function(value) {
}
render: function() {
return <div>
<Child doSome={this.doSomething} />
</div>
}
})
var Child = React.createClass({
onClick:function() {
this.props.doSome(value); // doSomething is undefined
},
render: function() {
return <div onClick={this.onClick}></div>
}
})
var Parent=React.createClass({
doSomething:函数(值){
}
render:function(){
返回
}
})
var Child=React.createClass({
onClick:function(){
this.props.doSome(value);//doSomething未定义
},
render:function(){
返回
}
})
用新道具克隆孩子
您可以使用迭代子元素,然后使用新的道具克隆每个元素(浅合并)。例如:
constchild=({doSomething,value})=>(
doSomething(值)}>单击我
);
类父类扩展了React.Component{
doSomething=值=>{
log(“值为:,value的子对象调用的doSomething”);
}
render(){
const childrenWithProps=React.Children.map(this.props.Children,child=>{
//检查isValidElement是一种安全的方法,也可以避免类型脚本错误
if(React.isValidElement(子项)){
返回React.cloneElement(子级,{doSomething:this.doSomething});
}
返回儿童;
});
返回{childrenWithProps};
}
}
函数App(){
返回(
);
}
render(,document.getElementById(“容器”)代码>
我需要修复上面已接受的答案,以便使用that而不是this指针使其工作map功能范围内的该未定义剂量测量功能
var Parent = React.createClass({
doSomething: function() {
console.log('doSomething!');
},
render: function() {
var that = this;
var childrenWithProps = React.Children.map(this.props.children, function(child) {
return React.cloneElement(child, { doSomething: that.doSomething });
});
return <div>{childrenWithProps}</div>
}})
var Parent=React.createClass({
doSomething:function(){
console.log('doSomething!');
},
render:function(){
var=这个;
var childrenWithProps=React.Children.map(this.props.Children,函数(child)){
return React.cloneElement(child,{doSomething:that.doSomething});
});
返回{childrenWithProps}
}})
更新:此修复程序适用于ECMAScript 5,在ES6中,无需使用var=this要获得更简洁的方法,请尝试:
<div>
{React.cloneElement(this.props.children, { loggedIn: this.state.loggedIn })}
</div>
{React.cloneElement(this.props.children,{loggedIn:this.state.loggedIn})}
编辑:
要与多个单独的子项(子项本身必须是组件)一起使用,可以执行以下操作。在16.8.6中测试
<div>
{React.cloneElement(this.props.children[0], { loggedIn: true, testPropB: true })}
{React.cloneElement(this.props.children[1], { loggedIn: true, testPropA: false })}
</div>
{React.cloneElement(this.props.children[0],{loggedIn:true,testPropB:true})
{React.cloneElement(this.props.children[1],{loggedIn:true,testPropA:false})
试试这个
<div>{React.cloneElement(this.props.children, {...this.props})}</div>
{React.cloneElement(this.props.children,{…this.props}}
使用react-15.1对我有效。这是最巧妙的方法:
{React.cloneElement(this.props.children, this.props)}
向孩子们传递道具。
看到所有其他答案了吗
通过组件树传递共享的全局数据
上下文被设计为共享可被视为React组件树的“全局”数据,例如当前经过身份验证的用户、主题或首选语言。一,
免责声明:这是一个更新的答案,之前的答案使用了旧的上下文API
它基于消费者/提供原则。首先,创建您的上下文
const { Provider, Consumer } = React.createContext(defaultValue);
然后使用via
<Provider value={/* some value */}>
{children} /* potential consumers */
</Provider>
{children}/*潜在消费者*/
及
{value=>/*根据上下文值*/}呈现某些内容
当提供程序的值属性更改时,作为提供程序的后代的所有使用者都将重新呈现从提供者到其后代使用者的传播不受shouldComponentUpdate方法的约束,因此即使祖先组件退出更新,使用者也会被更新。1
完整示例,半伪代码
import React from 'react';
const { Provider, Consumer } = React.createContext({ color: 'white' });
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: { color: 'black' },
};
}
render() {
return (
<Provider value={this.state.value}>
<Toolbar />
</Provider>
);
}
}
class Toolbar extends React.Component {
render() {
return (
<div>
<p> Consumer can be arbitrary levels deep </p>
<Consumer>
{value => <p> The toolbar will be in color {value.color} </p>}
</Consumer>
</div>
);
}
}
从“React”导入React;
const{Provider,Consumer}=React.createContext({color:'white'});
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
值:{color:'black'},
};
}
render(){
返回(
);
}
}
类工具栏扩展了React.Component{
render(){
报税表(
消费者可以任意选择深度
{value=>工具栏将采用颜色{value.color}}
);
}
}
1您不再需要{this.props.children}
。现在,您可以使用Route
中的render
包装子组件,并像往常一样传递道具:
<BrowserRouter>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/posts">Posts</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<hr/>
<Route path="/" exact component={Home} />
<Route path="/posts" render={() => (
<Posts
value1={1}
value2={2}
data={this.state.data}
/>
)} />
<Route path="/about" component={About} />
</div>
</BrowserRouter>
- 家
- 职位
- 关于
(
)} />
Parent.jsx:
import React from 'react';
const doSomething = value => {};
const Parent = props => (
<div>
{
!props || !props.children
? <div>Loading... (required at least one child)</div>
: !props.children.length
? <props.children.type {...props.children.props} doSomething={doSomething} {...props}>{props.children}</props.children.type>
: props.children.map((child, key) =>
React.cloneElement(child, {...props, key, doSomething}))
}
</div>
);
从“React”导入React;
const doSomething=值=>{};
const Parent=props=>(
{
!道具| |!道具。孩子们
?加载…(至少需要一个孩子)
:!props.children.length
?{props.children}
:props.children.map((child,key)=>
cloneElement(child,{…道具,键,doSomething}))
}
);
Child.jsx:
import React from 'react';
/* but better import doSomething right here,
or use some flux store (for example redux library) */
export default ({ doSomething, value }) => (
<div onClick={() => doSomething(value)}/>
);
从“React”导入React;
/*但最好在这里进口一些东西,
或者使用一些flux存储(例如redux库)*/
导出默认值({doSomething,value})=>(
doSomething(值)}/>
)
import React from 'react';
/* but better import doSomething right here,
or use some flux store (for example redux library) */
export default ({ doSomething, value }) => (
<div onClick={() => doSomething(value)}/>
);
import React from 'react';
import { render } from 'react-dom';
import Parent from './Parent';
import Child from './Child';
render(
<Parent>
<Child/>
<Child value='1'/>
<Child value='2'/>
</Parent>,
document.getElementById('...')
);
<div>
{ React.Children.map(this.props.children, child => React.cloneElement(child, {...this.props}))}
</div>
<div className="parent">
{React.Children.map(this.props.children, child => React.cloneElement(child, {className:'child'}))}
</div>
<div>{React.cloneElement(this.props.children, {...this.props})}</div>
React.cloneElement(element, props, ...children);
<element.type {...element.props} {...props}>{children}</element.type>
var newChildren = React.Children.map(this.props.children, function(child) {
return React.cloneElement(child, { foo: true })
});
// Render method of Parent component
render(){
let props = {
setAlert : () => {alert("It works")}
};
let childrenWithProps = React.Children.map( this.props.children, function(child) {
if (React.isValidElement(child)){
return React.cloneElement(child, props);
}
return child;
});
return <div>{childrenWithProps}</div>
}
var newChildren = this.props.children.map((child) => {
const className = "MenuTooltip-item " + child.props.className;
return React.cloneElement(child, { className });
});
return <div>{newChildren}</div>;
React.cloneElement(
element,
[props],
[...children]
)
<element.type {...element.props} {...props}>{children}</element.type>
render() {
const newElements = [];
React.Children.forEach(this.props.children,
child => newElements.push(
React.cloneElement(
child,
{...this.props, ...customProps}
)
)
)
return (
<div>{newElements}</div>
)
}
render() {
let updatedChildren = React.Children.map(this.props.children,
(child) => {
return React.cloneElement(child, { newProp: newProp });
});
return (
<div>
{ updatedChildren }
</div>
);
}
render() {
return (
<div>
{
React.cloneElement(this.props.children, {
newProp: newProp
})
}
</div>
);
}
import * as React from 'react';
// React.createContext accepts a defaultValue as the first param
const MyContext = React.createContext();
class Parent extends React.Component {
doSomething = (value) => {
// Do something here with value
};
render() {
return (
<MyContext.Provider value={{ doSomething: this.doSomething }}>
{this.props.children}
</MyContext.Provider>
);
}
}
class Child extends React.Component {
static contextType = MyContext;
onClick = () => {
this.context.doSomething(this.props.value);
};
render() {
return (
<div onClick={this.onClick}>{this.props.value}</div>
);
}
}
// Example of using Parent and Child
import * as React from 'react';
class SomeComponent extends React.Component {
render() {
return (
<Parent>
<Child value={1} />
<Child value={2} />
</Parent>
);
}
}
class SomeComponent extends React.Component {
render() {
return (
<Parent>
<Child value={1} />
<SomeOtherComp><Child value={2} /></SomeOtherComp>
</Parent>
);
}
}
{React.isValidElement(this.props.children)
? React.cloneElement(this.props.children, {
...prop_you_want_to_pass
})
: null}
class Child extends React.Component {
render() {
return <div className="Child">
Child
<p onClick={this.props.doSomething}>Click me</p>
{this.props.a}
</div>;
}
}
class Parent extends React.Component {
doSomething(){
alert("Parent talks");
}
render() {
return <div className="Parent">
Parent
{this.props.render({
anythingToPassChildren:1,
doSomething: this.doSomething})}
</div>;
}
}
class Application extends React.Component {
render() {
return <div>
<Parent render={
props => <Child {...props} />
}/>
</div>;
}
}
const Parent = ({children}) => {
const doSomething(value) => {}
return children({ doSomething })
}
class Child extends React {
onClick() => { this.props.doSomething }
render() {
return (<div onClick={this.onClick}></div>);
}
}
<Parent>
{(doSomething) =>
(<Fragment>
<Child value="1" doSomething={doSomething}>
<Child value="2" doSomething={doSomething}>
<Fragment />
)}
</Parent>
const Parent = (props) => {
const attributeToAddOrReplace= "Some Value"
const childrenWithAdjustedProps = React.Children.map(props.children, child =>
React.cloneElement(child, { attributeToAddOrReplace})
);
return <div>{childrenWithAdjustedProps }</div>
}
export const Context = createContext<any>(null);
export const ComposableContext = ({ children, ...otherProps }:{children:ReactNode, [x:string]:any}) => {
const context = useContext(Context)
return(
<Context.Provider {...context} value={{...context, ...otherProps}}>{children}</Context.Provider>
);
}
function App() {
return (
<Provider1>
<Provider2>
<Displayer />
</Provider2>
</Provider1>
);
}
const Provider1 =({children}:{children:ReactNode}) => (
<ComposableContext greeting="Hello">{children}</ComposableContext>
)
const Provider2 =({children}:{children:ReactNode}) => (
<ComposableContext name="world">{children}</ComposableContext>
)
const Displayer = () => {
const context = useContext(Context);
return <div>{context.greeting}, {context.name}</div>;
};
import React from 'react';
const withForm = (ViewComponent) => {
return (props) => {
const myParam = "Custom param";
return (
<>
<div style={{border:"2px solid black", margin:"10px"}}>
<div>this is poc form</div>
<div>
<ViewComponent myParam={myParam} {...props}></ViewComponent>
</div>
</div>
</>
)
}
}
export default withForm;
const pocQuickView = (props) => {
return (
<div style={{border:"1px solid grey"}}>
<div>this is poc quick view and it is meant to show when mouse hovers over a link</div>
</div>
)
}
export default withForm(pocQuickView);
import React from "react";
const Parent = ({ children }) => {
const { setCheckoutData } = actions.shop;
const { Input, FieldError } = libraries.theme.components.forms;
const onSubmit = (data) => {
setCheckoutData(data);
};
const childrenWithProps = React.Children.map(
children,
(child) =>
React.cloneElement(child, {
Input: Input,
FieldError: FieldError,
onSubmit: onSubmit,
})
);
return <>{childrenWithProps}</>;
};
<ParentComponent {...anyAdditionalProps}>
{
(actualPropsToPass) => <ChildComponent>{children(actualPropsToPass)}</ChildComponent>
}
</ParentComponent>