I am rendering a simple react component, where no state and props are set
I am logging text to console only once inside the render function but it's logged twice:
rendering counter
rendering counter
Below is the code of the component counter.js
import React, { Component } from "react";
class Counter extends Component {
render() {
console.log("rendering counter"); //this is printed two times
return <span className={"badge m-3 badge-primary"}>counter</span>;
}
}
export default Counter;
And index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import * as serviceWorker from "./serviceWorker";
import "bootstrap/dist/css/bootstrap.css";
import Counter from "./components/counter";
ReactDOM.render(
<React.StrictMode>
<Counter />
</React.StrictMode>,
document.getElementById("root")
);
serviceWorker.unregister();
it seems that the render function in the component is called two times. But why is that?
As it was written in docs:
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following methods:
Class component constructor method
The render method
setState updater functions (the first argument)
The static getDerivedStateFromProps lifecycle
The shouldComponentUpdate method
Related
I'm learning React and I have a problem trying to read my props in a child component.
The child component is:
const HelloWorldApp = ( props ) => {
console.log(props);
return (<>
<h2> {props} </h2>
</>
);
}
export default HelloWorldApp;
The parent is:
import React from 'react';
import {createRoot} from 'react-dom/client';
import HelloWorldApp from './FirstApp';
import { SecondApp } from './SecondApp';
import './styles.css';
createRoot(document.getElementById('root')).render(HelloWorldApp());
createRoot(document.getElementById('raiz')).render(SecondApp());
1) What is the problem?
2) How can I pass props from the parent to the children component?
I think the problem is in the render function. You need something like this:
createRoot(document.getElementById('root'))
.render(<HelloWorldApp />);
In react , you don't need to render all the components in separate CreateRoot..
render your child component with props inside the parent component
The parent Component
import React from 'react';
import {createRoot} from 'react-dom/client';
import HelloWorldApp from './FirstApp';
import './styles.css';
createRoot(document.getElementById('root')).render(<HelloWorldApp data="propsData" />);
The child Component
const HelloWorldApp = ( props ) => {
console.log(props);
// {data: "dummyData"}
return (<>
// you can't able to render object inside the jsx
<h2> {props.data} </h2>
</>
);
}
export default HelloWorldApp;
The structure React program is on constantly changing over the time, whereby i recommend you use command npm create-react-app to have the latest standards of programming in that framework.
Only one createRoot is necessary in React renderize DOM, and i recommend you receive parameters with destructuring in child component, the parameters must been passed in JSX tags as attributes
I have a react component which I later render inside my index.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
App.jsx
import SomeComponent from "./Components/SomeComponent ";
function App() {
return <SomeComponent />
}
export default App;
SomeComponent.jsx (random name of component just for the example)
function SomeComponent() {
//some code
return ...
}
export default SomeComponent;
The problem is that I see a lot of people using
class SomeComponent extends React.Component {
componentDidMount()
//some code
render() {
return ...
}
}
And I want to use that "componentDidMount()" that I see in a lot of code examples, but in my way of doing things, it seems to don't be possible.
But... it is possible? or there is another similar method that can I use?
Thanks.
In the functional components, from React 16.8, we have React Hooks. And we can use useEffect() Hook to simulate what componentDidMount() does in a class based component. However, You will need to pass second argument as state value to the useEffect(), only then it behaves like componentDidMount() whenever the state value gets modified.
Something like this:
const [stateValue,useStateValue] = useState("enjoy");
useEffect(()=>{
// ... Your code
},[stateValue]);
import React, { useContext } from "react";
import { ContextProvider, MyContext } from "./Context/MyContext";
import "./styles.css";
export default function App() {
const value = useContext(MyContext);
console.log(value);
return (
<ContextProvider>
<div className="App">{value}</div>
</ContextProvider>
);
}
If I want to consume the useContext exactly on App Component. I get the value as undefined on App Component but the value of all other component is okay. So, I want to know what is the mechanism behind it. Why I can't access to useContext in App component.
The ContextProvider provides the values within your Context to all it's child components. The value you are supplying to your <div> comes from the parent component of ContextProvider in your case, ie the App. At this point your Provider has still not been set up, you have to wrap App inside provider to access the values of the context. In other words the Provider needs to be the Parent of app to provide it values and not the other way around
my selectors are executing before the component in which they are mapped are rendered. Why would this be? For example in the code below, the messages selector is executed before the Component renders. Thanks!
import React from 'react';
import {connect} from 'react-redux';
import * as selectors from './selectors';
const Component = ({message}) => (
<div>
{message}
</div>
);
const mapStateToProps = (state, props) => ({
message: selectors.message(state, props),
});
export default connect(mapStateToProps)(Component);
In React-Redux v5, the internal selector that implements mapState is initialized in the wrapper component constructor, and is called right away as part of that process.
In React-Redux v6, that internal selector is created in the wrapper component constructor, but called during the render process.
I am writing this question cause I would like to ask you for some help in how to use the redux on my functional components. I had a look at other examples with React components but I cannot understand how to get the "store" value in functional components.
My idea is to use my
store.getState()
To check states and interact with the UI, inside my functional component but I cannot make it happen.
Any help please ?
For example, a functional component :
import React from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Header.css';
import { Navbar, Nav } from 'react-bootstrap';
import HeaderMenu from '../HeaderMenu';
import cx from 'classnames';
function Header() {
return (
<Navbar fluid fixedTop id="Header" className={s.navContainer}>
<Nav block className={cx(s.HeaderTitle, s.hideOnSmall)}>Project title</Nav>
<HeaderMenu />
</Navbar>
);
}
export default withStyles(s)(Header);
How can I use the "store" object inside my Header component ? It works on my App component, just I don't know how to use it within my components.
My questions are:
Should I use actions for retrieving the state instead ??
Should I pass the store object component to the component properties?
Thanks in advance!
EDIT :
I am using https://github.com/kriasoft/react-starter-kit
with the redux branch https://github.com/kriasoft/react-starter-kit/tree/feature/redux
As of version 7.x react-redux now has hooks for functional components.
Header.jsx
import React from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Header.css';
import { Navbar, Nav } from 'react-bootstrap';
import HeaderMenu from '../HeaderMenu';
import cx from 'classnames';
import { useSelector } from 'react-redux'
function Header() {
const store = useSelector(store => store)
return (
<Navbar fluid fixedTop id="Header" className={s.navContainer}>
<Nav block className={cx(s.HeaderTitle, s.hideOnSmall)}>Project title</Nav>
<HeaderMenu />
</Navbar>
);
}
export default withStyles(s)(Header);
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux'
import store from './store'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
As Dan Abramov mentioned in his insanely famous Egghead.io series, presentational component shouldn't be aware of Redux store and shouldn't use it directly. You should create something called container component, which will pass necessary state fields + action callbacks to your presentational component via properties.
I highly recommend to watch Dan Abramov's Egghead.io series if above concepts are not familiar to you. Patterns he is describing there are de facto standard style guide for writing React+Redux applications nowadays.
If you want to get the Redux state on a functional component, you either have to manually connect the component and Redux, which is very tedious. You would have to access the reducer variable inside your React Component, meaning import the reducer into the component file among other configurations.
This would interfere with other benefits you would normally get, such as action creators, dispatching actions automatically through middleware, and more.
A cleaner idea is to just use the Provider Component that comes with React-Redux to turn your Header component into a Container. A Container is a react component that 'listens for' any changes that have been made to the store. You are essentially wrapping your Header component in a higher order component that is connected directly to the redux store.
This way is more scalable and you can easily create a boilerplate file that can be used with any React/Redux project.
Try to understand the individual modules/components a boilerplate project contains before going with it. If you are new to react (and its complementary libraries) I recommend you start here:
https://github.com/petehunt/react-howto
For redux:
http://redux.js.org/
These are both great ressources which clarify the majority of react related questions on stackoverflow.
You can use react-redux library, and using connect you will access your store data as a component props - it's easy and efficient.