如何将反应组件传递到另一个反应组件中以转换第一个组件的内容?

时间:2014-09-11 21:13:29

标签: javascript reactjs

有没有办法将一个组件传递到另一个反应组件?我想创建一个模型反应组件并传入另一个反应组件以转换该内容。

编辑:这是一个reactJS codepen,说明了我尝试做的事情。 http://codepen.io/aallbrig/pen/bEhjo

HTML

<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'));

13 个答案:

答案 0 :(得分:157)

您可以使用this.props.children呈现组件包含的所有子项:

const Wrap = props => <div>{props.children}</div>

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

答案 1 :(得分:98)

注意我提供了更深入的答案here

运行时包装器:

这是最惯用的方式。

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是&#34;特殊道具&#34;在React中,上面的示例是语法糖,并且(几乎)等同于<Wrapper children={<App/>}/>

初始化包装器/ HOC

您可以使用Higher Order Component(HOC)。它们最近已添加到official doc

// 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将渲染短路一步,而在运行时包装器的情况下,子prop可能总是不同的ReactElement和原因即使您的组件扩展PureComponent,也要重新渲染。

请注意,Redux的connect曾经是一个运行时包装程序,但已更改为HOC,因为如果使用pure选项(默认情况下为true),它允许避免无用的重新呈现

在渲染阶段永远不应该调用HOC,因为创建React组件可能很昂贵。你应该在初始化时调用这些包装器。

请注意,在使用上述功能组件时,HOC版本不提供任何有用的优化,因为无状态功能组件未实现shouldComponentUpdate

此处有更多解释:https://stackoverflow.com/a/31564812/82609

答案 2 :(得分:18)

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} />

答案 3 :(得分:11)

Facebook建议使用无状态组件 资料来源:https://facebook.github.io/react/docs/reusable-components.html

  

在理想的世界中,大多数组件都是无状态的   功能因为将来我们也能够提高性能   通过避免不必要的优化特定于这些组件   检查和内存分配。这是推荐的模式,何时   可能的。

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);

答案 4 :(得分:8)

我更喜欢使用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> 

答案 5 :(得分:4)

您可以通过传递组件。道具并用插值渲染它。

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

然后,您将传入名为prop的{​​{1}},这将是一个React组件。

答案 6 :(得分:4)

您可以将其作为常规道具传递: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>

答案 7 :(得分:2)

仅次于游戏,但这是一个强大的HOC模式,可通过将其作为道具来覆盖该组件。简单而优雅。

假设library(leaflet) #lat and long of the Subway stations SubwayStation_long<-c(174.764164,174.764290) SubwayStation_lat<-c(-36.877022,-36.877844) #lat and long of the Passengers Passagier_long<-c(174.764, 174.764436, 174.764336, 174.764044, 174.764034, 174.763, 174.7641, 174.7645, 174.764290, 174.764068, 174.764352, 174.764467) Passagier_lat<-c(-36.877, -36.8770099, -36.8770199, -36.8770189, -36.8770189, -36.876, -36.8779, -36.8778, -36.877844, -36.877102, -36.877814, -36.877900) tiles = getAllLeafletTiles() tiles = tiles[c(1,3,27)] map <- leaflet() for (provider in tiles) { map <- map %>% addProviderTiles(provider, group = provider) } map <- addLayersControl( map, baseGroups = tiles,c("Station","Passengers"), options = layersControlOptions(collapsed = FALSE)) map <- addMeasure(map, primaryLengthUnit = "kilometers", primaryAreaUnit = "sqmeters", activeColor = "#3D535D", completedColor = "#006400") map<-addCircles(map,SubwayStation_long,SubwayStation_lat, group = "Station",radius = 15) map<-addMarkers(map,Passagier_long,Passagier_lat,group = "Passengers", clusterOptions = markerClusterOptions(freezeAtZoom = FALSE)) map 呈现一个虚构的MyComponent组件,但是您希望允许A的自定义替代,在本示例A中,它包装了BA中,并附加“!”文字道具:

<div>...</div>

答案 8 :(得分:1)

实际上,您的问题是如何编写高阶组件(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>
    )
}

答案 9 :(得分:0)

这里是父 List react组件的示例,并且whos道具包含react元素。在这种情况下,仅传入一个 Link 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')
);

答案 10 :(得分:0)

是的,您可以使用props来实现,您可以像props一样将组件的数据作为对象传递,然后可以在组件内部导入另一个组件并与prpps数据动态绑定。 read more about react component

答案 11 :(得分:0)

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

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

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

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

答案 12 :(得分:-1)

您可以将您的反应组件传递给另一个组件并从子组件发出函数

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>
)