Giter VIP home page Giter VIP logo

async-props's People

Contributors

dlmr avatar ingro avatar insin avatar ntkoopman avatar rexxars avatar romeovs avatar ryanflorence avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

async-props's Issues

Still maintained/relevant?

Hello, I noticed that the project has not been very active during the last year. Is it still relevant or did I miss a new and more main stream way to handle the the same purpose?

loadProps in child route breaks <Link /> in react-router 2.0

When I have

static loadProps(params, cb) {
  cb(null, { test: 'hi'})
}

inside a component, linking to that page does not work. The moment I remove the loadProps property and reload the page, using <Link /> to that page works again. The url updates but the page does not actually switch unless you do a refresh.

Edit: Also noticed this only happens when loadProps is inside of a child route component.

renderLoading prop doesn't work

Hi.
I tried to show loading message through renderLoading the callback never triggered.
Hope to pre-release for [email protected] or hot-fix it.

Thank you!

Edit
renderLoading is only used in first-loading in client-side. I got it incorrectly. Hope to add callback for every loading.

Setting Page Title from async-props

Hey, sometimes I need to set the page title based on something returned from an api. For now I've been doing something like this inside of loadPropsOnServer

if(asyncProps.propsArray[asyncProps.propsArray.length - 1].title) {
  title = asyncProps.propsArray[asyncProps.propsArray.length - 1].title
}

I'm just curious if @ryanflorence would like to add a better way to do this or if that is outside of the scope of this package.

Why The <script> String?

Nice library, it will solve many problems!

So, attempting to render a string "<script>" block in a react component used for server side rendering is way more ugly than it should be, needing to completely take control of a containing element.

So sure, no problem yeh, we can:

<script
  dangerouslySetInnerHTML={{
    __html: `window.__ASYNC_PROPS__ = '${JSON.stringify(asyncProps.propsArray)}';`,
  }}
/>

But, why have the script string... an object is far more composable, it's a primitive structure. The script string seems to just overcomplicate things?

Why the generated script string?
Also, why should __ASYNC_PROPS__ contain a serialised JSON instead of just a normal JS object?

loadProps Nirvana

I discovered that the static loadProps method has to be defined in all Components, otherwise the async-props will not receive an callback and update - easy enough.

So i defined empty callbacks for testing purposes

statics: {
  loadProps: function(params, cb) {
    cb(null);
  }
}

funny thing: the { loading } = this.props in the root component does get updated correctly but the { this.props.children } does not recognize any changes...

so i had wo hack the system a bit and call it with an zero timeout and whoop - it works:

statics: {
  loadProps: function(params, cb) {
    setTimeout(function() {
      cb(null);
    },0);
  }
}

don't know it is an bug - or an feature :)

Wait on promise in addition to callback

The current implementation only supports rendering after loadProps invokes a callback. Wouldn't it be an interesting addition to also support loadProps returning a Promise and render after the promises resolve?

components of undefined

Been getting this message on the server, not 100% sure why:
screen shot 2015-12-28 at 11 22 11 pm

I can add if(!_ref) return on line 134 to fix it. My guess is this happens when I am not defining loadProps? Not sure.

Uncaught Error: Invariant Violation

invariant.js:39 Uncaught Error: Invariant Violation: You're trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure. React cannot handle this case due to cross-browser quirks by rendering at the document root. You should look for environment dependent code in your components and ensure the props are the same client and server side:
(client) <html><head><noscript dat
(server) <html data-reactid=".1xl9

My client code:

render(<Router history={history} RoutingContext={AsyncProps}>{routes}</Router>, window.document);

Old:

render(<Router history={history}>{routes}</Router>, window.document);

Server:

res.status(200).send(renderToString(<AsyncProps {...renderProps} {...asyncProps} />));

Old:

res.status(200).send(renderToString(<RoutingContext {...renderProps} />));

If I return the old client code (remove 'RoutingContext={AsyncProps}') no error.

Warning: React.createElement: type should not be null, undefined, boolean, or number.

I am trying async-props with my project

app.js

var React = require('react');
var ReactDOM = require('react-dom');
var Router = require('react-router').Router;
var browserHistory = require('react-router').browserHistory;
var AsyncProps = require('async-props');

var rootRoute = {
    component: 'div',
    childRoutes: [{
        path: '/',
        component: require('./components/App.js'),
        indexRoute: {
            component: require('./components/Home.js')
        },
        childRoutes: [
            require('./routes/Page.js'),
            {
                path: '*',
                component: require('./components/NotFound.js')
            }
        ]
    }]
};

ReactDOM.render(
    <Router history={browserHistory} routes={rootRoute} render={(props) => (
        <AsyncProps {...props} renderLoading={() => <div>Loading...</div>}/>
    )}/>,
    document.getElementById('app')
);

but is always get this error:
qq 20160526151250

if I remove render prop in Router, the error will gone:

ReactDOM.render(
    <Router history={browserHistory} routes={rootRoute}/>,
    document.getElementById('app')
);

package.json

...
    "async-props": "^0.3.2",
    "react": "^15.1.0",
    "react-dom": "^15.1.0",
    "react-router": "^2.4.1",
...

npm-scripts/postinstall.js global babel

What?

This is just a question. I'm trying to introduce async-props into my package.json. I've babel as a dependency but async-props post install was failing when doing npm install.

Only after install babel globally the install worked. What I'm missing. It's necessary post install script?

Use case: loading throbber

If you wanted to have a "something is loading" throbber at the top level of your app to indicate loading with async-props is currently happening somewhere in the route hierarchy, is there any way async-props can provide that information, or would you have to manage it externally via your static loadProps hooks?

async-props interferes with dynamic segments

I've made a fork where I was trying to build an async-props example with RR2, using its latest from master, but noticed that dynamic segments are not working correctly. The address bar will update but the next view will not load. Hitting the back button at that point will cause it to render the view that previously would have rendered.

Here's my example: https://github.com/bdefore/react-router/blob/async-props-example/examples/async-props/app.js

The only difference between it working correctly and causing this behavior is in removing AsyncProps from render:

<Router render={(props) => <AsyncProps {...props} />} history={browserHistory}>

vs:

<Router history={browserHistory}>

[discuss] async-props work with falcor(async model)

Nice async-props and example !

I try to use falcor to build async model(JSON Graph: remote data model, ui model). And I use async-props to fetch all the state(falcor model get) in route component.

When dispatch a action(falcor model set/call), the server will return updated JSON Graph. The app will reload async props of all route components, then render.

falcor-react

example: https://github.com/ustccjw/tech-blog

Purpose and motivation?

I feel like the readme of this repo needs an explanation for the motivation behind this library.

As far as I can see, the main purpose is providing a known interface that a server can use to know when a route has all of its asynchronous resources loaded that are required for a full render. I hope I'm correct here, but I only discovered this after reading into server side react for the first time.

Possible to disable AsyncProps loading behavior?

Howdy!

I'm curious if you'd be open to allowing for a new API (via props on AsyncProps) that would allow individual components to handle their own loading state, rather than AsyncProps only rendering the new Component once its loadProps method calls the callback?

Right now I can work around this via:

static loadProps({ params }, cb) {
  if (__CLIENT__) { // Flag injected by webpack
    cb();
  }

  api.makeRequest().then(cb);
}

However I would like to make this the default behavior.

Thoughts?

Is the loadPropsOnServer example up-to-date?

I tried following the server example in README.md but got the error cb is not a function. After looking at loadPropsOnServer it looks like it's expecting 3 arguments where the last is the callback whereas the example has 2 unless I'm missing something?

What should be passed as the second argument, loadContext?

Other than that this library solves a much needed problem so thanks very much :)

loadProps won't be called in class unless class is prefixed with "export default"

I could be wrong here, but from testing, there appears to be a bug in how the static method loadProps is called.

For example, the method won't be called (shown in code below):

export default ({ children }) => (
   children || <DefaultPage />
);


class DefaultPage extends Component {
  constructor(props) {
    super(props);
  }

  static loadProps(stuff, cb) {
    console.log('async props called');
    cb(null, {});
  }

  render() {
    return (
      <div className="pw__wrapper">
      </div>
    );
  }
}

But in the example below, the method will be called

export default class DefaultPage extends Component {
  constructor(props) {
    super(props);
  }

  static loadProps(stuff, cb) {
    console.log('async props called');
    cb(null, {});
  }

  render() {
    return (
      <div className="pw__wrapper">
      </div>
    );
  }
}

Not sure if this intended or not?

Rethink the script string

I know it's been discussed in #4 but I want to bring it up again here.

The way the script thing works now, the user-land code gets handed a string of the form:

"<script>__ASYNC_PROPS__ = /* .... */ </script>"

This is quiet handy in the case you use js template strings to insert the script into your html (as shown in the README):

html = (markup, script) => `
  <html>
    <!-- ... -->
    ${markup}
    ${script} 
  </html>
`

I for one, do not use js string templates to generate my html, I use react components. To get the script working I now need to do either:

<span dangerouslySetInnerHTML={{__html: script }} />

which adds a superflous <span>. Or I can make my markup a bit cleaner with:

const data = script.replace(/^<script>/, '').replace(/<\/script>$/, '');
//...
<script dangerouslySetInnerHTML={{__html: data }} />

Both of these solutions seem a bit hacky. I prefer to keep dangerouslySetInnerHTML out of my code
completely. I also would like to be able to minify the script code when in production.

How can we fix this? It seems like there are a lot of people who are fine with the way things are now, but
we should be able to expand the use-case to other users.

I propose the following: make the script parameter be an object that knows how to transform the data to any of the preferred forms (the string with script tags, the pure object, ....) so people can choose which they like. So people can call script.asString() or script.data() to be able to use their use case.

SSR issue with ReactRouter 2.0

HI ๐Ÿ˜ƒ
I'm testing master branch of this on my private universal app,
and encountered a problem on SSR.

// client
render(
  <Router
    history={this.history}
    render={props => (
      <AsyncProps {...props} />
    )}>
    {this.routes}
  </Router>
);

// server
// .. in `loadPropsOnServer`'s cb
renderToString(
  <AsyncProps {...renderProps} {...asyncProps} />
);

It works, but checksum was invalid warning occurs like this:

Warning: React attempted to reuse markup in a container but the checksum was invalid.
...
(client) <noscript data-reacti
(server) <div data-reactid=".y`

I've tried <Router render={props => <AsyncProps {...props} />} ... instead of just <AsyncProps /> on server side too, but it doesn't work.
fetching and bind scriptString is fine, but App's react components render on client side, after intial server rendered.
am I missed something?

thanks

componentWillReceiveProps logic missing some scenarios

Here's an example where I'm going up the route tree from a /:user/:repo to a different /:userwhere there are User and Repo route components - it never gets to compare the user props against eachother so the user data doesn't get reloaded:

async-props-cwrp

Seems like it should check the components one at time for equality them param changes inside this block.

Edit: live, heavy meta, example: https://insin.github.io/react-nwb-github-issues/#/rackt/async-props/9

Extra parameters to `loadProps`

I want to access my flux instance in loadProps. On the server side I can manipulate params to include my flux instance, but it feels a bit hacky, but on the client-side the invocation of loadProps is hidden by RoutingContext={AsyncProps}. What would be the best way to access a request-specific variable in loadProps?

throw error with [email protected]

Hi. I got an error in client-side:
2015-12-25 3 28 12

client-side react render code:

  <Router history={history} createElement={AsyncProps}>
    <Route path="/" component={App}>
      <Route path="*" component={ContentPage} />
      <IndexRoute component={HomePage} />
    </Route>
  </Router>

RoutingContext attribute did not work on [email protected], I tried createElement attributes as similar. Is there plan to fix it? or should I downgrade react-router?

  • renderProps give 'undefined' components. so when check loadProps, there's need to filter undefined components as:
const components = renderProps.components.filter(x => !!x);
      renderProps.components = components;

Thank you!

Breaks createBrowserHistory

I just tried to use async-props with react-router, and createBrowserHistory and everything works fine apart from one thing:

Here's a short form of my code:
(CJSX) (React Router: 1.0.3, Async-props: 0.2.2 )

My routing file:

ReactDom.render(    
    <Router RoutingContext={AsyncProps}  history={ createBrowserHistory() }>
        { routes }
    </Router>
,document.getElementById("app"))

And the components both look something like this.

class Home extends React.Component


    @contextTypes:
        history: require("react-router").PropTypes.history

    displayName: "Home"

I can call @context.history.push etc. and it navigates properly, but if you use the back button in the browser nothing happens. I tracked it down to the RoutingContext. When I remove it everything works.

(Navigation using <Link> also works, but the back button is broken too)

I hope my explanation didn't sound too crazy and you somewhat understand my problem.. Thanks in advance!

Using async-props with Alt.js

Since the HoC or AltContainer wraps your component and makes it impossible to call any static method on your component you have to use a util from alt called statics

import connectToStores from 'alt-utils/lib/connectToStores';
import statics from 'alt-utils/lib/statics';

class SomeComponent extends React.Component{
   static getStores() {
        return [SomeStore]
    }

    static getPropsFromStores() {
        return SomeStore.getState()
    }

    render(){
       return ....
    }
}

//declare your functions as constants
const loadProps = (params, cb) => {
  cb(null, {
      tacos: [ 'Pollo', 'Carnitas' ]
    })
}

//pass them to statics first param (used ES6 desctructor)
export default statics(
  { loadAsyncData },
  connectToStores(WorkflowPage)
);

Promise support

Hey, Iโ€™d like to use async-props in my current project, but it lacks Promise support. How about mixing new and old school, huh?

If you like the idea, Iโ€™m willing to implement this feature myself.

redirectToLogin middleware

Hey,

I've implemented this approach into my boilerplate (isomorphic with dynamic component loading) for displaying a Progress Bar when a dynamic route is loading.

I got a very similar setup to the example 'auth-with-shared-root' provided in the react-router examples https://github.com/rackt/react-router/blob/master/examples/auth-with-shared-root/config/routes.js

Some childRoutes got an onEnter middleware.

{ onEnter: redirectToLogin,
  childRoutes: [
    // Protected routes that don't share the dashboard UI
    { path: '/user/:id',
      getComponent: (location, cb) => {
        require.ensure([], (require) => {
          cb(null, require('../components/User'))
        })
      }
    }
    // ...
  ]
},

Any of these endpoints get the error Uncaught TypeError: Cannot read property 'loadProps' of undefined when routing to them. But when i remove the onEnter method and require.ensure it directly thise work fine.

Do i have to pass different attributes when using onEnter??

Passing data through to loadProps

I have a use case where I need to get the request object inside of loadProps if I am on the server. Is there any way to pass down something through the AsyncProps component? How do you propose adding this?

I am doing renderProps.params.token = req.session.token above loadPropsOnServer for now.

consider flattening __ASYNC_PROPS__ for client hydration

First, thank you for releasing this library. I'm still fairly new to React and have been trying to learn it without jumping to the complexity of something like redux before it is necessary. This library fits very well in the space where I thought I would need to build something custom for myself.

With the goal of trying to keep complexity low, I've started with a setup that is a bit different than what is suggested here. For my server-side rendering, I am not using async-props, but am passing the initial props through a custom createElement function. The need for this custom function for such simple use cases still seems unnecessary, but thats a different topic.

Because of this approach, I have not differentiated between which props are needed for each of the routable components for that page load, but rather just have a flat object with all of my data for that page. Therefore, I have to jump through a few extra hoops and leverage some knowledge about which components should be rendered, which doesn't feel like it should be the responsibility for this layer of my app.

It sounds like the current state of this project is still a pretty early design, so I'm hoping that things could still be flexible enough to support this type of use case. Would it be reasonable to support a flattened object literal for __ASYNC_PROPS__, either instead of the current list of objects, or at least optionally? This would enable the flexibility to use async-props client-side with an alternative server-side rendering technique without the requirement to jump through hoops to match the expected list.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.