6

Still have stupid questions about ReactJS =) Is there any way to add public functions to React components? I'm trying to make something like this:

var LoginForm = React.createClass({
    getInitialState: function() {
    },  
    render: function() {
    },
    MyFunc: function () {
    }
})
...
var login_form = LoginForm({});
React.renderComponent(login_form, document.body);
...
login_form.MyFunc (); <-- error

Can you explain please what I'm doing wrong?

3 Answers 3

13

You're not supposed to use a component's method outside of the component itself (or by passing it as a callback to a child component). You should treat these as private methods.

However, you can use a feature of React called statics to provide functions that are available from outside the component. However these should be treated like static functions of a class, and as a result they don't get access to the internals of an instance of your component (such as this.props or this.state).

Here's an example of some statics setup for a component:

var Component = React.createClass({
    statics: {
        // these functions are available outside the component
        renderToBody: function() {
            React.renderComponent(
                <Component />,
                document.body
            );
        }
    },

    // cannot access this function outside the component
    getHelloWorld: function() {
        return 'Hello World!';
    },

    render: function() {
        return (
            <div>{this.getHelloWorld()}</div>
        );
    }
});

So if we call React.renderComponent(Component({}), elem) then the component would render to elem but because of the static you could call Component.renderToBody() and it would render the component directly to the <body> element.

IE: Functions defined inside the component's statics object are available directly as static functions. However you must remember that they are static in that they are not part of an instantiated component object, they are just functions you can call on the class.

The whole idea with react is that components are as self-contained as possible. You should never need to access a component instance function directly from outside a component as what you should do instead is just change the props for the component and re-render it so that it, internally, can change.

Here's an example of that:

var Component = React.createClass({
    propTypes: {
        // always get in the habbit of using propTypes!
        message:    React.PropTypes.string.isRequired,

        show:       React.PropTypes.bool
    },
    render: function() {
        return (
            <div style={{display: this.props.show ? 'block' : 'none'}}>
                {this.props.message}
            </div>
        );
    }
});

Whereas you might have created a method show() on the component instead (so that you could do component.show(true) or component.show(false) to show/hide - you instead pass it as a property for the same result.

Calling React.renderComponent(Component({message: 'foo', show: true}), elem) will render the component visible, re-rendering with show: false will hide it, etc. Same result, but with props, which is the react way.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much Mike, you helped me a lot! Can I ask last question please? As I understanding I can mount many Components to one node? So I can itarate them? For example if I nounted 3 vicible componentts and then want to hide second.
You can only mount one component on a given html element. However, one of the best ways to deal with multiple components is to mount a parent component and then just make everything else you need a child of that parent. But yes you can iterate and mount multiple instances of the same component. In react this is as simple as iterating and pushing components to an array, then rendering the array inside the render function of a component such as <div>{yourArray}</div>
0

The simple answer is that LoginForm({}) does not return the component. It returns a descriptor object that will be used by React to instantiate the component later. There are two ways you can access the actual component:

  • as this in the component methods
  • by giving the component a ref=name prop; the actual component will be available in the creator, as this.refs.name by the time the creator's componentDidMount executes.

http://facebook.github.io/react/docs/more-about-refs.html

Comments

0

It is possible by using the result of the rendering function:

var login_form = React.renderComponent(LoginForm({}), document.body);
login_form.MyFunc();
login_form.setProps({loaded: true});

The use case for this is that you can call setProps on the root component (but only on the root).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.