The link for the code is : https://gist.github.com/justgoof9/b0ff1033cc83edeb72c687da0de4f89f
The problem with this is that It keeps on searching it and it never stops. How do I make it so that after the first search it stops?
As per your code here https://gist.github.com/justgoof9/b0ff1033cc83edeb72c687da0de4f89f
you are doing search in render and while you setState your render is being called again so this is causing infinite search so move that code to lifecycle method like componentWillMount or componentDidMount like this:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const API_KEY = "9f64caf0";
class App extends Component {
constructor(props){
super(props);
this.state={
movies:[],
}
}
componentDidMount(){
const imdb = require("imdb-api");
imdb
.search({ title: "Game Of Thrones" }, { apiKey: API_KEY })
.then((movies)=>{this.setState({movies})})
console.log(this.state.movies)
}
render() {
return (
<div >
</div>
);
}
}
export default App;
You should use componentDidMount commit lifecycle hook for api calls not render or even componentWillMount
From React documentation - https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data
I am Quoting specific lines from the above page.
There is a common misconception that fetching in componentWillMount lets you avoid the first empty rendering state. In practice this was never true because React has always executed render immediately after componentWillMount. If the data is not available by the time componentWillMount fires, the first render will still show a loading state regardless of where you initiate the fetch. This is why moving the fetch to componentDidMount has no perceptible effect in the vast majority of cases.
Related
How can i declarate componentDidMount without creating class extends react component? For example render() declarates with react-dom package, maybe is exist another package for componentDidMount?
class App extends Component {
constructor(){
// do something
}
componentDidMount(){
// js code must run after page loaded
}
render(){
return(
<div className="app">
</div>
);
}
}
export {App};
The same thing with component constructor()
const App = () => {
// constructor and componentDidMount does not work here
// js code must run after page loaded
return (
<div className="app">
</div>
);
};
export {App};
First of all, what you want to achieve is fully Meteor independent. It's a pure React problem that could exist with any backend. What you want to achieve can be done using the useEffect() hook for which you'll find the documentation right here:
https://reactjs.org/docs/hooks-reference.html#useeffect
Here is a great article explaining how to replace lifecycle methods with hooks:
https://dev.to/trentyang/replace-lifecycle-with-hooks-in-react-3d4n
In your case, for componentDidMount you'll have to do the following:
useEffect(() => {
// js code must run after page loaded
}, []);
In the final array you have to put dependency that will retrigger the hook if you need. To imitate a simple componentDidMount an empty array is generally the solution.
I was fetching data using onclick button but now i wanna fetch on page load using componentDidMount().
My fetch function is under action file and i am using react native with redux.
My function name is submitToServer(){}. How can i call it on componentDidMount?
Can anyone help me?
import React from 'react';
class SomeComponent extends React.Component {
componentDidMount() {
// here you fetch your data
submitToServer();
}
render() {
// ...
}
}
The submitToServer() call will then trigger some Redux store changes, which the react-redux library will process and trigger a properties change event in your SomeComponent component (if connected, of course). Then, your component will be re-rendered, and you would be able to use the retreived data.
I have a component that i'm loading via react-loadable. The component that is being loading has some logic in componentWillReceiveProps for detecting if it needs to get some more data, etc.
When loaded via react loadable, it calls render 1 time, and componentWillReceiveProps is never called.
import React from 'react'
import Loadable from 'react-loadable'
import Loading from 'components/Loading'
const LoadableThing = Loadable({
loader: () => import('components/Thing'),
loading: Loading,
render(loaded, props) {
let Component = loaded.default;
return <Component {...props}/>
}
});
export default LoadableThing
And this component is included in another component that's making some initial data calls and sending the results to the Thing
any thoughts? It's calling return <Component again, but that seems like it's creating a new component in that case.
I'll try and keep it simple and concise.
I have started a simple page with React Webpack and Firebase included.
I set the initial state for DVDLibrary as null.
Inside the componentDidMount function I set the state as a firebase snapShot.val().
When I console.log the DVDLibrary state, it logs null.
import React from "react";
import ReactDOM from "react-dom";
import firebase from 'firebase';
export default class Front extends React.Component {
constructor(){
super();
this.state = {
DVDLibrary : null
};
};
componentDidMount(){
firebase.database().ref().on('value',snapShot => {
this.setState({
DVDLibrary: snapShot.val()
});
});
console.log(this.state.DVDLibrary);
};
render()....
}
If I include the contents of the componentDidMount function inside the constructor function, the console logs as expected but the new state doesn't seem to leave the scope of the constructer.
I tried to include a console.log in a componentDidUpdate function but it didn't log anything.
What am I doing wrong?
Any help is much appreciated.
Thanks All.
Moe
Using Mobx, after updating the store (i.e. clicking the button) the component does not re-render. I've installed mobx devtools which shows nothing after the initial load, and there is no error in the console. Any ideas what I've done wrong?
Store.js:
import { observable } from 'mobx';
class Store {
#observable me;
constructor() {
this.me = 'hello';
}
change_me(){
this.me = 'test 1234';
}
}
export default Store;
layout.js:
import React from "react";
import { observer } from 'mobx-react';
#observer
export default class Layout extends React.Component{
render(){
return(
<div>
<h1>{this.props.store.me}</h1>
<button onClick={this.on_change}>Change</button>
</div>
)
}
on_change = () => {
this.props.store.change_me();
}
}
index.js:
import React from "react";
import ReactDOM from "react-dom";
import Layout from "./components/Layout";
import Store from "./Store";
import DevTools, { configureDevtool } from 'mobx-react-devtools';
// Any configurations are optional
configureDevtool({
// Turn on logging changes button programmatically:
logEnabled: true,
// Turn off displaying conponents' updates button programmatically:
updatesEnabled: false,
// Log only changes of type `reaction`
// (only affects top-level messages in console, not inside groups)
logFilter: change => change.type === 'reaction',
});
const app = document.getElementById('app');
const store = new Store();
ReactDOM.render(
<div>
<Layout store={store} />
<DevTools />
</div>
, app);
I would start by adding #action to your change_me() function. From what I understand, it's not always completely required, but I have encountered problems like this in my own code several times when I've forgotten to add it.
Additionally post your .babelrc as #mweststrate suggested, as it will help others to check that the proper plugins are loaded.
Just add makeObservable(this); in constructor function like below
constructor() {
makeObservable(this);
}
My guess would be to have uninitialized #observable. It is very counter-intuitive, but Babel doesn't handle those well. Even adding #observable me = undefined might help (see the generated js code when you assign something there. Generally I'd remove constructor completely and move the initialization to declaration (i.e. #observable me = "hello" an no constructor). It should then work fine.
Watch the binding of the this context.
<button onClick={this.on_change}>Change</button>
the this reference will not be to the class, so likely when you are actually clicking it is going to say something along the lines of no props on undefined. Changing to:
<button onClick={this.on_change.bind(this)}>Change</button>
should fix it. Or better yet, bind the context in the constructor so its not re-binding on every render
constructor(props) {
super(props)
this.on_change = this.on_change.bind(this)
}
then you can go back to your