如何在一个react组件传递到另一个react组件,以穿透第一个组件的内容?

有没有办法将一个组件传递给另一个react组件?我想创建一个模型react组件,并传入另一个react组件,以透光该内容。

编辑:这里是一个reactJS代码,说明了我正在尝试做什么。http://codepen.io/aallbrig/pen/bEhjo

超文本标记语言

<div id="my-component">
<p>Hi!</p>
</div>

ReactJS

/**@jsx React.DOM*/


var BasicTransclusion = React.createClass({
render: function() {
// Below 'Added title' should be the child content of <p>Hi!</p>
return (
<div>
<p> Added title </p>
{this.props.children}
</div>
)
}
});


React.renderComponent(BasicTransclusion(), document.getElementById('my-component'));
328097 次浏览

你可以通过传入一个组件。道具和渲染它与插值。

var DivWrapper = React.createClass({
render: function() {
return <div>{ this.props.child }</div>;
}
});

然后你将传入一个名为childprop,它将是一个React组件。

你可以使用this.props.children来呈现组件包含的任何子组件:

const Wrap = ({ children }) => <div>{children}</div>


export default () => <Wrap><h1>Hello word</h1></Wrap>

注意,我提供了一个更深入的答案在这里

运行时包装:

这是最地道的方式。

const Wrapper = ({children}) => (
<div>
<div>header</div>
<div>{children}</div>
<div>footer</div>
</div>
);


const App = () => <div>Hello</div>;


const WrappedApp = () => (
<Wrapper>
<App/>
</Wrapper>
);

注意,children是React中的“特殊道具”,上面的例子是语法糖,(几乎)相当于<Wrapper children={<App/>}/>


初始化包装器/ HOC

你可以使用高阶分量 (HOC)。它们最近被添加到官方文档

// Signature may look fancy but it's just
// a function that takes a component and returns a new component
const wrapHOC = (WrappedComponent) => (props) => (
<div>
<div>header</div>
<div><WrappedComponent {...props}/></div>
<div>footer</div>
</div>
)


const App = () => <div>Hello</div>;


const WrappedApp = wrapHOC(App);

这可能会带来(一点点)更好的性能,因为包装器组件可以通过shouldComponentUpdate提前一步短路呈现,而在运行时包装器的情况下,子道具可能总是不同的ReactElement,并导致重新呈现,即使您的组件扩展了PureComponent。

注意,Redux的connect曾经是一个运行时包装器,但被改为HOC,因为如果你使用pure选项(默认为true),它允许避免无用的重新渲染。

你不应该在渲染阶段调用HOC,因为创建React组件的开销很大。您应该在初始化时调用这些包装器。


注意,当像上面那样使用函数组件时,HOC版本不提供任何有用的优化,因为无状态函数组件不实现shouldComponentUpdate

更多解释在这里:https://stackoverflow.com/a/31564812/82609

Facebook推荐使用无状态组件 来源:https://web.archive.org/web/20160608001717/http://facebook.github.io/react/docs/reusable-components.html < / p >
在理想的情况下,大多数组件都是无状态的 函数,因为在未来我们还会研究性能 特定于这些组件的优化,避免不必要的 检查和内存分配。这是推荐的模式 可能的。< / p >
function Label(props){
return <span>{props.label}</span>;
}


function Hello(props){
return <div>{props.label}{props.name}</div>;
}


var hello = Hello({name:"Joe", label:Label({label:"I am "})});


ReactDOM.render(hello,mountNode);
const ParentComponent = (props) => {
return(
{props.childComponent}
//...additional JSX...
)
}


//import component
import MyComponent from //...where ever


//place in var
const myComponent = <MyComponent />


//pass as prop
<ParentComponent childComponent={myComponent} />

我更喜欢使用React内置API:

import React, {cloneElement, Component} from "react";
import PropTypes from "prop-types";


export class Test extends Component {
render() {
const {children, wrapper} = this.props;
return (
cloneElement(wrapper, {
...wrapper.props,
children
})
);
}
}


Test.propTypes = {
wrapper: PropTypes.element,
// ... other props
};


Test.defaultProps = {
wrapper: <div/>,
// ... other props
};

然后你可以用你想要的东西替换包装器div:

<Test wrapper={<span className="LOL"/>}>
<div>child1</div>
<div>child2</div>
</Test>

你可以把它作为一个普通的道具传递:foo={<ComponentOne />}

例如:

const ComponentOne = () => <div>Hello world!</div>
const ComponentTwo = () => (
<div>
<div>Hola el mundo!</div>
<ComponentThree foo={<ComponentOne />} />
</div>
)
const ComponentThree = ({ foo }) => <div>{foo}</div>

虽然有点晚了,但这里有一个强大的HOC模式,可以通过将组件作为道具来覆盖组件。它简单而优雅。

假设MyComponent呈现一个虚构的A组件,但你想允许自定义重写A,在本例中B,它将A包装在<div>...</div>中,并将"!"附加到文本道具:

import A from 'fictional-tooltip';


const MyComponent = props => (
<props.A text="World">Hello</props.A>
);
MyComponent.defaultProps = { A };


const B = props => (
<div><A {...props} text={props.text + '!'}></div>
);


ReactDOM.render(<MyComponent A={B}/>);

下面是父组件列表的一个例子,它的props包含一个react元素。在这种情况下,只传入一个链接 react组件(如dom渲染中所示)。

class Link extends React.Component {
constructor(props){
super(props);
}
render(){
return (
<div>
<p>{this.props.name}</p>
</div>
);
}
}
class List extends React.Component {
render(){
return(
<div>
{this.props.element}
{this.props.element}
</div>
);
}
}


ReactDOM.render(
<List element = {<Link name = "working"/>}/>,
document.getElementById('root')
);

实际上,您的问题是如何编写高阶组件(HOC)。使用HOC的主要目标是防止复制粘贴。你可以把你的HOC写成一个纯功能组件或一个类,这里有一个例子:

class Child extends Component {
render() {
return (
<div>
Child
</div>
);
}
}

如果你想把你的父组件写成一个基于类的组件:

class Parent extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}

如果你想把你的父组件写成一个函数组件:

const Parent = props => {
return (
<div>
{props.children}
</div>
);
}

您可以将组件作为道具传递,并使用与使用组件相同的方式。

function General(props) {
...
return (<props.substitute a={A} b={B} />);
}


function SpecificA(props) { ... }
function SpecificB(props) { ... }


<General substitute=SpecificA />
<General substitute=SpecificB />

你可以将你的react组件传递给另一个组件,并从child发出函数

import CustomerFilters;


parent:


const handleFilterChange = (value) => {
console.log(value)
}


<DataGrid
contentName="customer"
fetchFilterComponents = {<CustomerFilters onSelectFilter={handleFilterChange} />}
</DataGrid>




child:
CustomerFilters
return (


<select className="filters-dropdown" onChange={onSelectFilter}>
<option>Select Filter</option>
{customerFilterOptions?.map((filter: any) => {
return <option value={filter.value}>{filter.name}</option>;
})}
</select>
)

让我们创建一个包装器组件:

export const Wrapper = (props) => {
return(<>
<Menu />
{props.children}
<Footer />
</>
)
}

您现在可以将您的新结构包含到现有结构中。< br > 你将把组件包含在一个路由中,例如:

 <Route path="/"  element={<Wrapper><ExampleComponent /></Wrapper>} />