Firebase and React with react-snapshot (pre-rendering) - reactjs

I"m new to firebase, just wrote a little simple test react component before putting all of data on to firebase, but unfortunately I couldn't make it work with Server Side Pre-Rendering. It's very important to make it SEO friendly for me, and I've searching around on the internet for the solution, but still couldn't really figure it out. please help me out with this. thanks very much in advance.
The simple code below will only generate the initial state with React-Snapshot, when I open the the page it will show initial state and then update to newer state. But I need to make the initial state object fetching data directly from Firebase and generate static html with React-Snapshot.
class FirebaseTestingComponent extends Component {
constructor(){
super();
this.state = {
speed: 10
};
}
componentWillMount(){
const rootRef = firebase.database().ref().child('react');
const speedRef = rootRef.child('speed');
speedRef.on('value', snap => {
this.setState({
speed: snap.val()
});
});
}
render(){
return (
<div>
<h1>{this.state.speed}</h1>
</div>
);
}
}

By SEO friendly I assume you want static content instead of dynamic (not an expert on SEO) but firebase runs asynchronously especially when you use .on() that's like websocket, doesn't matter if you do willmount or didmount this case.
My humble suggestion for the design is to fetch from firebase in your server before render the page (firebase support java and node for sure, not sure about the rest), and set initial state with that value you fetched, that will guarantee your initial state is from firebase. From that you can still use that .on() for later value coming in.

Related

ReactJS - Triggering Re-render from external Process

Im very new at React and Frontend development. Its literally my first Project now and I have design problem listening to external events. So basically I want to build a UI that only changes on external Events, meaning you control it with another Process (e.g. an AI that triggers the changes). The App should listen to incoming messages and depending on the message it should update the UI.
My idea was to make the Component, that receives the messages from outside, an observable and notify the MainApp of the React-Ui. The following code should give an idea to my approach.
export default class App extends Component {
constructor(props){
super (props);
this.state = {mode: "idle"};
this.observable = new Observable();
this.observable.add((m) => mode(m));
}
mode(m){
this.setState({
mode: m
});
}
render() {
return (
<div>
<Home/>
<ComponentA mode={this.state.mode}/>
<ComponentB mode={this.state.mode}/>
</div>
)
}}
My Question now is, Is this a good way to update the UI or are there maybe better ways or pattern that I can use or that are common in Frontend-Development?
Your approach is totally valid, I don't see any issues with it.
You could try initializing the observable in a lifecycle method instead like componentDidMount. You could even use redux to manage the data passed from the observable.

How prevent calling same api in different components in react js

I am working large reactjs application,In that application so many components are there and so many api services also there.
My problem is how to prevent calling same api in different components.
Actually i want to call api one time then ,i will use that api response entire application ,so that we can prevent calling same api in different components.
So please give me any solution.
check the below demo code:
enter code here
`FirstComponent:
——————————————
Class FirstComponent extends Component {
constructor(props){
this.setState={}
}
componentDidMount() {
this.props.dispatch(getById(1)); //here first time I am calling api
}
render(){
return(
———HTML Code HERE———
)
}
const mapStateToProps = state => {
  return {
    registrationData: state.RegistrationDemand.registrationData
// here I am getting response through redux reducer store
    };
};
export default compose(
  translate,
  withRouter,
  connect(mapStateToProps)
)(FirstComponent);
SecondComponent:
——————————————
Class SecondComponent extends Component {
constructor(props){
this.setState={}
}
componentDidMount() {
this.props.dispatch(getById(1)); //here I need to prevent this second time api calling
}
render(){
return(
———HTML Code HERE———
)
}
const mapStateToProps = state => {
  return {
    registrationData: state.RegistrationDemand.registrationData
//without calling second component,If I use this one first time when I redirect to this page data is coming hereabout when I refresh second time it is getting null.
    };
};
export default compose(
  translate,
  withRouter,
  connect(mapStateToProps)
)(SecondComponent);`
You can actually call the API once your application is mounted. Usually this is done via componentDidMount or if you're using hooks, you can add it inside useEffect.
And you can just pass down props.
A more better solution is to use redux to your project, wherein the whole state of your application is inside a store in which you can connect using react-redux.

Preserve internal state on page refresh in React.js

It must be pretty regular issue.
I'm passing props down to the children and I'm using it there to request to the endpoint. More detailed: I'm clicking on the list item, I'm checking which item was clicked, I'm passing it to the child component and there basing on prop I passed I'd like to request certain data. All works fine and I'm getting what I need, but only for the first time, ie. when refreshing page incoming props are gone and I cannot construct proper URL where as a query I'd like to use the prop value. Is there a way to preserve the prop so when the page will be refresh it will preserve last prop.
Thank you!
(You might want to take a look at: https://github.com/rt2zz/redux-persist, it is one of my favorites)
Just like a normal web application if the user reloads the page you're going to have your code reloaded. The solution is you need to store the critical data somewhere other than the React state if you want it to survive.
Here's a "template" in pseudo code. I just used a "LocalStorage" class that doesn't exist. You could pick whatever method you wanted.
class Persist extends React.Component {
constuctor(props) {
this.state = {
criticalData = null
}
}
componentDidMount() {
//pseudo code
let criticalData = LocalStorage.get('criticalData')
this.setState({
criticalData: criticalData
})
}
_handleCriticalUpdate(update) {
const merge = {
...LocalStorage.get('criticalData')
...update
}
LocalStorage.put('criticalData', merge)
this.setState({
criticalData: merge
})
}
render() {
<div>
...
<button
onClick={e => {
let update = ...my business logic
this._handleCriticalUpdate(update) //instead of set state
}}
>
....
</div>
}
}
By offloading your critical data to a cookie or the local storage you are injecting persistence into the lifecycle of the component. This means when a user refreshes the page you keep your state.
I hope that helps!

in react Redux how to structure app to decouple component from state atom

in an redux app, using connect to fetch data from state is the way to go. problem is i find my self tighly coupling the component with the state atom.
in case i want to change the structure of the state tree, all components that used to consume such state will break.
so how to decouple them ?
example
initialState = {
users: { ids:[1,2] , byId:{1:{name:'user 1'},2:{name:'user 2'} }
posts: { ids:[1,2] , byId:{1:{title:'post 1'},2:{title:'post 1'} }
access : {1:[1,2],2:[1,2]} //post_id : [user_id who can see post]
}
in this simple state, i'm descriping that i have 2 users, and 2 posts, both posts are visible to both users..
in a component that list posts and users the connect can be
render(){
let {posts,access,currentUser} = this.props;
let my_posts = posts.ids.map(post_id=>posts.byId[post_id])
.filter(post=>(access[post.id].indexOf(currentUser.id)>-1)
//above map will return posts, and filter will filterout posts user dont have access to.
}
connect( (state,prop)=>{currentUser:users[prop.user_id],posts,access})(Component);
<Component user_id={1} />
the problem here is that the render function of the component do lots of manipulation with the state to render correct data. it would be much better if i can do something like
render(){
let my_posts = Posts.ofUser(currentUser.id)
//now Posts should be a service that has access to state and return the needed data.
}
how can i create such Object that deals with the state and expose an api that components and connect functions contact for information.
i read about reselect alot, but how to implement it ?
The easiest way to decouple state shape from your components is querying any of your state prop through selectors.
It adds a bit of boilerplate code, but once is done, you'll get a fully testable bridge between your components and application state.
To get started with selectors, take a look to Redux Docs Computing derivated data page.
Reselect is just an utility to create memoized selectors.

React with REST API - State or GET on mount?

We're currently building a React-Redux frontend with a REST API backend powered by Node. I'm unsure about whether to use a Redux or a simple call to the API on mounting the component.
The component is a simple list of profiles which are going to be displayed throughout (but not constantly) the site.
Sorry for asking this. Maybe there's something to read through available?
I would advice you to take a look at two things:
1) The first React tutorial on Facebook is very underrated:
https://facebook.github.io/react/docs/thinking-in-react.html
It exposes a very clear way to think about how to think about the tree structure of your views.
2) From there, move to reading about Containers and Components:
https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
This post explains that React components too often do two things: act as renderers and as controllers (taking on both the V and the C on MVC).
Now, what your React view needs is a controller. Fetching it whenever you mount the component overlaps two different concerns: how to display the information and how to fetch it.
You could do it with a single, bigger React component that manages the complete state of your application:
class MyApp extends React.Component {
componentDidMount() {
fetch('/profiles').then(res => res.json().then(::this.setState))
}
render() {
if (this.state) {
return <ProfileList profiles={this.state} />
} else {
return <span>Loading...</span>
}
}
}
That would be your "Container". Your "Component" is a pure representation of the list of profiles, that needs not care about how that information was retrieved:
class ProfileList extends React.Component {
render() {
return <ul>
{
this.props.profiles.map(
profile => <li key={profile.id}>{profile.name}</li>
)
}
</ul>
}
}
Redux is just another way of doing this that enables better reuse of information, and makes that same information available to different components (hiding the instance of the "store" as a mixin). That MyApp class on top of your structure serves a similar function to the Provider class in redux: allowing child components to access information needed to display themselves.

Resources