在覆盖父母的父道具

时间:2016-02-26 17:22:58

标签: reactjs

我将使用一个例子来解释我正在寻找的功能。

 const Grandparent = React.createClass({
    render: function(){
        return (<div>
                    <Parent>
                        <button className={this.props.parentClassName} />
                    </Parent>
                <div>
                    )
    }
});

const Parent = React.createClass({
        render: function(){
            const childrenWithProps = React.Children.map(this.props.children, (child) => {
                return React.cloneElement(child, {parentClassName: 'Murphy'});
            });
            return (<div>
                {childrenWithProps}
            </div>)
        }
    });

我希望Parent组件拦截在GrandParent中设置的props.parentClassName并更改它,或者如果它不存在则创建它。

为了让按钮接收正确的parentClassName,我必须创建一个自定义Button组件来接收来自Parent组件的道具,就像这样

React.createClass({
    render: function(){
        return (<button className={this.props.parentClassName} />)
    }
});

我希望尽可能避免这种情况,因为它会在声明初始组件时提取出我想要显示的代码。

所以我想要这个

 React.createClass({
        render: function(){
            return (<div>
                        <Parent>
                            <button className={
//From Parent Component and not the GrandParent Component
this.props.parentClassName

} />
                        </Parent>
                    <div>
                        )
        }
    });

而不是

 React.createClass({
        render: function(){
            return (<div>
                        <Parent>
                            <Button />
                        </Parent>
                    <div>
                        )
        }
    });

const Button = React.createClass({
        render: function(){
            return (<button className={this.props.parentClassName} />)
        }
    });

<Parent>组件返回props.parentClassName,而不是<GrandParent>组件。

2 个答案:

答案 0 :(得分:2)

我明白你想要做什么。我相信这不是你要找的答案,但React不是那样设计的。你可以(你真的不应该,但你可以)使用一个焊剂容器,并在你的焊剂商店中保存父类的className,并在你上面显示的类中调用它。

我会重新考虑如何使用React方式而不是使用Flux或尝试制作一个hacky解决方法。

根据我的经验,在渲染这样的自定义组件时:

enter code here
    try {

        //Create a new PHPMailer instance
        $mail = new PHPMailer();

        $mail->isSMTP();
        //Enable SMTP debugging
        // 0 = off (for production use)
        // 1 = client messages
        // 2 = client and server messages
        $mail->SMTPDebug   = 2;
        $mail->DKIM_domain = '**********';

        $mail->Debugoutput = 'html';

        $mail->Host        = "a2plcpnl0321.prod.iad2.secureserver.net";

        $mail->Port        = 465;

        $mail->SMTPAuth    = true;
        //Username to use for SMTP authentication
        $mail->Username    = "***************.com";
        //Password to use for SMTP authentication
        $mail->Password    = "**99KKll";
        $mail->SMTPSecure  = 'ssl';
        //Set who the message is to be sent from
        $mail->setFrom('****************.com', '*******');
        //Set an alternative reply-to address
        //$mail->addReplyTo('replyto@example.com', 'First Last');
        //Set who the message is to be sent to
        $mail->addAddress('**************.com', '*****');

        //Set the subject line
        $mail->Subject = 'PHPMailer SMTP test';
        $mail->Body = "<i>This is the Link to change your password:</i>";
        //Replace the plain text body with one created manually
        $mail->AltBody = 'This is a plain-text message body';


        //send the message, check for errors
        if (!$mail->send()) {
            echo "Mailer Error: " . $mail->ErrorInfo;
        } else {
            echo "Message sent!";
        } 
        print_r($mail); 

你最好将return ( <customComponent> <button /> </customComponent> ); 作为这样的道具:

<button />

并在return ( <customComponent buttonElement={<button />} /> ); 类的渲染函数中将{this.props.buttonElement}渲染到您想要的位置。如果您不打算将按钮传递给customComponent的每个实例,则可以在customComponent的呈现函数中执行此操作:

customComponent

答案 1 :(得分:0)

  

我想要的是父组件拦截   props.parentClassName在GrandParent中设置并更改或创建它   如果它不存在。

组件无法拦截其父级的道具,因为它无法访问其父级,只能访问其子级!

我仍然不清楚你想要实现的目标......以下代码是否符合您的要求?

import _ from 'underscore';
import React from 'react';

class Grandparent extends React.Component
{
    render() {
        return (
            <div {... this.props}>
                <Parent>
                    <span>hello</span>
                    <span>welcome</span>
                    <span className="red">red</span>
                </Parent>
            </div>
        );
    }
}

// Parent component will add ``className="border"`` to each its
// child without ``className`` property.
class Parent extends React.Component
{
    render() {
        return (
            <div {... this.props}>
                {_.map(this.props.children, (v, k) =>
                    React.cloneElement(v, {className: v.props.className || 'border', key: k}))}
            </div>
        );
    }
}