How to pass server data into React component

11,535

Solution 1

The React way would be to load in the data via a RESTful API.

However, you could look into serverside rendering of React components with PHP V8JS. Not sure how stable it is, but if, it would be a very good/better alternative to the AJAX call on the client. It would look somewhat like this:

// the library
$react_source = file_get_contents('/path/to/build/react.js');
// all custom code concatenated
$app_source = file_get_contents('/path/to/custom/components.js');

$rjs = new ReactJS($react_source, $app_source);
$rjs->setComponent('MyComponent', array(
  'any'   =>  1,
  'props' =>  2
  )
);

/// ...

// print rendered markup
echo '<div id="here">' . $rjs->getMarkup() . '</div>';

If you actually want to render this in the browser, you can use plain Javascript instead of JSX:

<?php $username = 'Eric Andre'; ?>
<script type="text/javascript">
  ReactDOM.render(React.createElement(Greeting, { username: "<?php echo $username; ?>" }), document.body);
</script>

Another option would be to transform the JSX into plain Javascript with babel-browser and use <script type="text/babel">. Keep in mind that babel-browser is not in active development anymore and also not intended for production use.

<?php $username = 'Eric Andre'; ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.min.js"></script>
<script type="text/babel">
  ReactDOM.render( <Greeting username="<?php echo $username; ?>"/>, document.body );
</script>

Solution 2

Method 1: Define a global variable.

In your main PHP file:

<script>
    window.reactInit = {
        username: <?php echo $username; ?>
    };
</script>

In your component:

class Greeting extends React.Component {
    constructor(props) {
        super(props);
        this.username = reactInit.username;
    }
}

If you use Redux, you may find this method particularly useful. Because ANY of your reducers can access this global variable during building of the initial state.

Method 2: Use data-* attributes.

<div id="app" data-username="<?php echo $username; ?>"></div>

All data-* attributes are passed by using {...app.dataset}.

const app = document.getElementById('app');
ReactDOM.render(<Greeting {...app.dataset} />, app);

Now you can access your server data as ordinary props.

class Greeting extends React.Component {
    constructor(props) {
        super(props);
        console.log(this.props.username);
    }
}

This method is not so flexible as the previous one, but seems to be more consistent with React philosophy.

Solution 3

You could also take a look at https://github.com/erikras/react-redux-universal-hot-example for some examples on how to call RESTful APIs from a client.

Specifically it uses superagent to make the AJAX calls: https://github.com/visionmedia/superagent

Share:
11,535

Related videos on Youtube

Pete
Author by

Pete

I live near Seattle, WA and own and operate a design, development and animation business called Laterna Studio.

Updated on June 04, 2022

Comments

  • Pete
    Pete over 1 year

    I'm just learning React, and while I understand many of the basics there is one concept I haven't seen anyone cover: how do I take information loaded via the server-side language (e.g. PHP) and use it when loading up the React view?

    I would have expected that I'd just have the RenderDom call in my php view, such as:

    // In the pre-compiled JSX file
    var Greeting = React.createClass({
        render: function() {
            <div>
                <h1>Hello, { this.props.username }</h1>
            </div>
        }
    });
    
    // In my PHP view
    <script type="text/jsx">
        ReactDOM.render( <Greeting username="<?php echo $username; ?>"/>, document.body );
    </script>
    

    But that doesn't work; nothing is displayed. I'm thinking that's because the text/jsx script area doesn't get executed...but of course if I remove that there's a syntax error.

    Soo...I'm just wondering, what's the typical method for taking data loaded up from the DB and passing it into a React component?

    • Fazal Rasel
      Fazal Rasel about 7 years
      use ajax for data from backend.. that how SPA work..
    • Pete
      Pete about 7 years
      Yeaaaah...but then I have to do an AJAX call after page load...seems kinda sad.
    • jOshT
      jOshT about 7 years
      this.props.username will probably work. The script should be executed. Building an API backend might be preferred, but this should still work.
  • Davrick
    Davrick over 2 years
    I've tried your first method. But it doesn't seem to be working with react hook. Any ideas why ?
  • Ryan
    Ryan over 2 years
    I used your approach (Method 1) but needed to change reactInit.username to window.reactInit.username. I appreciate it's not the 'React' way, but it does save an API call for my use case.