saltyshiomix / react-ssr

React SSR as a view template engine
https://npm.im/@react-ssr/express
MIT License
267 stars 44 forks source link

[Question]: Redux example. #13

Closed ovidius72 closed 4 years ago

ovidius72 commented 4 years ago

Hi, do you have any example on how to send the state from the server to the client. Using redux for example, when you switch from a page to another, how do you manage the application state ?

saltyshiomix commented 4 years ago

@ovidius72 Thank you for your question!

You mean page transitions (with url) by using Redux?

Currently react-ssr provides only view template engine feature, so it might be difficult to do that.

I'll try to use Redux later :)

ovidius72 commented 4 years ago

I'm not referring to preserve the sate on page transitions itself but when a page is loaded. That could be the very first time the page is loaded or when one go to another page not using react-router thus asking the page content to the server.

I would like to send down the initial state for that particular page when rendering on the server. Please, look at this example from the redux documentation https://redux.js.org/recipes/server-rendering/

They send down a json object attached to the window.__PRELOADED_STATE global variable. Maybe there could be a way to do the same with the document page ? Anyway, since i've started playing around with react-ssr, i found that the initial state can also be send down as a Prop and then rebuilt in the client code.

However, it's a great job.

ovidius72 commented 4 years ago

Hey @saltyshiomix I'm sorry to bother you again but I'm having a problem with hot reload. When i make some change the page is fully reloaded

React_SSR_-__About__e_about_tsx____Projects_opa_tsnodessr_src_web-react_views__-_NVIM

I see this error in the console. Do you have any idea ? I guess it is something to do with webpack-dev-server.

saltyshiomix commented 4 years ago

@ovidius72

I tested:

But no errors found.

If you get this error everytime, could you tell me more information with an example repository?

(Anyway, this error is from webpack-dev-server.)

ovidius72 commented 4 years ago

Thanks @saltyshiomix Can you try using typescript ? It seems that when something changes in the index.tsx page the server is also restarted causing the page to refresh. I'll try to put online an example later.

saltyshiomix commented 4 years ago

Thank you, @ovidius72

But I'm already using TypeScript.

Anyway, I think react-ssr is not compatible or suitable for React Redux structures.

For example, let's see if we implemented views/todo.tsx like this:

interface TodoPageProps {
  todos: TodoState[];
}

const TodoPage = (props: TodoPageProps) => {
  const { todos } = props; // passed from the server

  const initialState = {
    todo: {
      todos,
    }
  };

  return (
    <Provider store={createStore(rootReducer, initialState)}>
      <h1>Todo List</h1>
      <AddTodo />
      <Todos />
    </Provider>
  );
};

export default TodoPage;

It's not impossible to implement, but in this case the code below is smarter than the above?

interface TodoPageProps {
  todos: TodoState[];
}

const TodoPage = (props: TodoPageProps) => {
  const { todos } = props; // passed from the server

  return (
    <React.Fragment>
      <h1>Todo List</h1>
      <AddTodo />
      <Todos todos={todos} />
    </React.Fragment>
  );
};

export default TodoPage;
saltyshiomix commented 4 years ago

@ovidius72

I'll try to add views/_app.(js|ts)x to tackle this issue :)

And we'll be able to use Redux like this:

views/_app.tsx

export default class extends ReactSsrApp {
  render() {
    const { todos, Component, ...otherProps } = this.props; // `todos` are passed from a server
    const initialState = { todo: { todos } };
    const store = createStore(rootReducer, initialState);
    return (
      <Provider store={store}>
        <Component {...otherProps} />
      </Provider>
    );
  }
}

If you have any ideas or advices, please let me know 🙌

ovidius72 commented 4 years ago

@saltyshiomix Thanks and sorry for the lacking of my responses but I've had no time in the last few days to test the issue again. I will do more tests during the next week hopefully.

saltyshiomix commented 4 years ago

@ovidius72

Thank you for your reply :)

No problem, I was bussy at work, too.

I want to add this feature in the next minor release. I'll implement and test it next few weeks :)

saltyshiomix commented 4 years ago

@ovidius72

Sorry for late reply.

I implemented examples/with-tsx-redux-todo.

If you have time, please try it :)

views/index.tsx

interface IndexPageProps {
  todos: Todo[];
};

const IndexPage = (props: IndexPageProps) => {
  // use server data as preloaded state
  const preloadedState = {
    todos: props.todos,
  };

  const store = createStore(rootReducer, preloadedState);

  return (
    <Provider store={store}>
      <AddTodo />
      <TodoList />
    </Provider>
  );
};

export default IndexPage;
saltyshiomix commented 4 years ago

@ovidius72 If any updates, feel free to reopen the issue :)