Hi I have one component in which I integrated the redux in my react application. I am opening second then third component. I don't want the pass the data which I obtained in first component to second then third in props.
I want to do this using redux store. Is there any way to do this ?
App.js
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import RoundedButton from "./RoundedButton";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import * as actions from "./actions/index";
class App extends Component {
constructor(props) {
super(props);
this.state = {
score: 0,
status: "",
userSelected: "",
computerSelected: "",
visibility: [true, true, true],
buttonVisibility: false
};
this.clickitem = this.clickitem.bind(this);
this.handlePlayAgain = this.handlePlayAgain.bind(this);
}
handlePlayAgain() {
this.setState({
buttonVisibility: false,
visibility: [true, true, true]
});
}
clickitem(user) {
var url = "http://localhost:4000/generate-random";
this.setState({ userSelected: user });
fetch(url)
.then(response => {
if (response.status >= 400) {
throw new Error("Bad response from server");
}
return response.json();
})
.then(data => {
var computer = data.item;
this.setState({ computerSelected: computer });
if (
(user === "Rock" && computer === "Scissors") ||
(user === "Paper" && computer === "Rock") ||
(user === "Scissors" && computer === "Paper")
) {
this.props.increment();
} else if (user === computer) {
this.props.doNothing();
} else {
this.props.decrement();
}
console.log(user + " " + computer);
console.log("------------------------------------");
App.contextTypes = { store: React.PropTypes.object };
let store = this.context.store;
console.log(store);
arrayvar = [];
var arrayvar = [];
if (user === "Rock" && computer === "Rock") {
arrayvar = [true, false, false];
} else if (user === "Paper" && computer === "Paper") {
arrayvar = [false, true, false];
} else if (user === "Scissors" && computer === "Scissors") {
arrayvar = [false, false, true];
} else if (
(user === "Rock" && computer === "Paper") ||
(user === "Paper" && computer === "Rock")
) {
arrayvar = [true, true, false];
} else if (
(user === "Rock" && computer === "Scissors") ||
(user === "Scissors" || computer === "Rock")
) {
arrayvar = [true, false, true];
} else if (
(user === "Paper" && computer === "Scissors") ||
(user === "Scissors" || computer === "Paper")
) {
arrayvar = [false, true, true];
}
this.setState({ visibility: arrayvar });
this.setState({
buttonVisibility: true
});
});
}
render() {
return (
<div className="CenterDiv">
<div className="AppTitle">
<b>Score: {this.props.score}</b>
<div>
{this.state.visibility[0]
? <RoundedButton
text="Rock"
clickitem={this.clickitem}
label={
this.state.userSelected === "Rock" &&
this.stateputerSelected === "Rock"
? "User & Computer Selected"
: this.state.userSelected === "Rock"
? "User Selected"
: this.stateputerSelected === "Rock"
? "Computer Selected"
: ""
}
/>
: null}
{this.state.visibility[1]
? <RoundedButton
text="Paper"
clickitem={this.clickitem}
label={
this.state.userSelected === "Paper" &&
this.stateputerSelected === "Paper"
? "User & Computer Selected"
: this.state.userSelected == "Paper"
? "User Selected"
: this.stateputerSelected === "Paper"
? "Computer Selected"
: ""
}
/>
: null}
{this.state.visibility[2]
? <RoundedButton
text="Scissors"
clickitem={this.clickitem}
label={
this.state.userSelected === "Scissors" &&
this.stateputerSelected === "Scissors"
? "User & Computer Selected"
: this.state.userSelected === "Scissors"
? "User Selected"
: this.stateputerSelected === "Scissors"
? "Computer Selected"
: ""
}
/>
: null}
</div>
<div className="Status">{this.props.status}</div>
{this.state.buttonVisibility
? <button onClick={this.handlePlayAgain} style={{ margin: 30 }}>
Play Again
</button>
: null}
</div>
</div>
);
}
}
function mapStateToProps(state) {
return { score: state.score, status: state.status };
}
export default connect(mapStateToProps, actions)(App);
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";
import "./index.css";
import { Provider } from "react-redux";
import { createStore } from "redux";
import scoreReducer from "./reducers";
let store = createStore(scoreReducer);
ReactDOM.render(
<Provider store={store}><App /></Provider>,
document.getElementById("root")
);
registerServiceWorker();
secondcomponent.js
export default class SecondComponent extends Component {
render() {
return (
// print score which is in redux
);
}
}
third component.js
export default class ThirdComponent extends Component {
render() {
return (
// print score which is in redux
);
}
}
Whats the way to have an access of redux store in multiple components ?
Hi I have one component in which I integrated the redux in my react application. I am opening second then third component. I don't want the pass the data which I obtained in first component to second then third in props.
I want to do this using redux store. Is there any way to do this ?
App.js
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import RoundedButton from "./RoundedButton";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import * as actions from "./actions/index";
class App extends Component {
constructor(props) {
super(props);
this.state = {
score: 0,
status: "",
userSelected: "",
computerSelected: "",
visibility: [true, true, true],
buttonVisibility: false
};
this.clickitem = this.clickitem.bind(this);
this.handlePlayAgain = this.handlePlayAgain.bind(this);
}
handlePlayAgain() {
this.setState({
buttonVisibility: false,
visibility: [true, true, true]
});
}
clickitem(user) {
var url = "http://localhost:4000/generate-random";
this.setState({ userSelected: user });
fetch(url)
.then(response => {
if (response.status >= 400) {
throw new Error("Bad response from server");
}
return response.json();
})
.then(data => {
var computer = data.item;
this.setState({ computerSelected: computer });
if (
(user === "Rock" && computer === "Scissors") ||
(user === "Paper" && computer === "Rock") ||
(user === "Scissors" && computer === "Paper")
) {
this.props.increment();
} else if (user === computer) {
this.props.doNothing();
} else {
this.props.decrement();
}
console.log(user + " " + computer);
console.log("------------------------------------");
App.contextTypes = { store: React.PropTypes.object };
let store = this.context.store;
console.log(store);
arrayvar = [];
var arrayvar = [];
if (user === "Rock" && computer === "Rock") {
arrayvar = [true, false, false];
} else if (user === "Paper" && computer === "Paper") {
arrayvar = [false, true, false];
} else if (user === "Scissors" && computer === "Scissors") {
arrayvar = [false, false, true];
} else if (
(user === "Rock" && computer === "Paper") ||
(user === "Paper" && computer === "Rock")
) {
arrayvar = [true, true, false];
} else if (
(user === "Rock" && computer === "Scissors") ||
(user === "Scissors" || computer === "Rock")
) {
arrayvar = [true, false, true];
} else if (
(user === "Paper" && computer === "Scissors") ||
(user === "Scissors" || computer === "Paper")
) {
arrayvar = [false, true, true];
}
this.setState({ visibility: arrayvar });
this.setState({
buttonVisibility: true
});
});
}
render() {
return (
<div className="CenterDiv">
<div className="AppTitle">
<b>Score: {this.props.score}</b>
<div>
{this.state.visibility[0]
? <RoundedButton
text="Rock"
clickitem={this.clickitem}
label={
this.state.userSelected === "Rock" &&
this.state.computerSelected === "Rock"
? "User & Computer Selected"
: this.state.userSelected === "Rock"
? "User Selected"
: this.state.computerSelected === "Rock"
? "Computer Selected"
: ""
}
/>
: null}
{this.state.visibility[1]
? <RoundedButton
text="Paper"
clickitem={this.clickitem}
label={
this.state.userSelected === "Paper" &&
this.state.computerSelected === "Paper"
? "User & Computer Selected"
: this.state.userSelected == "Paper"
? "User Selected"
: this.state.computerSelected === "Paper"
? "Computer Selected"
: ""
}
/>
: null}
{this.state.visibility[2]
? <RoundedButton
text="Scissors"
clickitem={this.clickitem}
label={
this.state.userSelected === "Scissors" &&
this.state.computerSelected === "Scissors"
? "User & Computer Selected"
: this.state.userSelected === "Scissors"
? "User Selected"
: this.state.computerSelected === "Scissors"
? "Computer Selected"
: ""
}
/>
: null}
</div>
<div className="Status">{this.props.status}</div>
{this.state.buttonVisibility
? <button onClick={this.handlePlayAgain} style={{ margin: 30 }}>
Play Again
</button>
: null}
</div>
</div>
);
}
}
function mapStateToProps(state) {
return { score: state.score, status: state.status };
}
export default connect(mapStateToProps, actions)(App);
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import registerServiceWorker from "./registerServiceWorker";
import "./index.css";
import { Provider } from "react-redux";
import { createStore } from "redux";
import scoreReducer from "./reducers";
let store = createStore(scoreReducer);
ReactDOM.render(
<Provider store={store}><App /></Provider>,
document.getElementById("root")
);
registerServiceWorker();
secondcomponent.js
export default class SecondComponent extends Component {
render() {
return (
// print score which is in redux
);
}
}
third component.js
export default class ThirdComponent extends Component {
render() {
return (
// print score which is in redux
);
}
}
Whats the way to have an access of redux store in multiple components ?
Share Improve this question asked Oct 17, 2017 at 18:58 N SharmaN Sharma 34.5k98 gold badges265 silver badges452 bronze badges 6 | Show 1 more comment2 Answers
Reset to default 15Any component that is wrapped with connect
:
connect(mapStateToProps, actions)(AnyComponent);
will have access to the entire redux
store.
With mapStateToProps
you can pass just relevant piece of data from the redux
store to the connected component via props
.
About component internal state
, my rule of thumb is to set internal state just for data that is relevant for the specific component.
For example, extend
or collapse
state for a Drop-down.
As for ajax
requests, if you already using redux
I highly recommend to use actions with thunks
or sagas
and pass the new fetched data through the redux
flow:
Action/thunk -> Reducers -> connected components.
Edit
As a followup to your comment,
You don't need to pass every component you want to connect to the Provider, you just pass a root component (App
in your case) and each child of App
can connect to redux
if necessary:
class SecondComponent extends Component {
render() {
return (
// print score which is in redux
<div>this.props.score</div>
);
}
}
export default connect(mapStateToProps)(SecondComponent);
And as well as for other components:
class ThirdComponent extends Component {
render() {
return (
// print score which is in redux
<div>this.props.score</div>
);
}
}
export default connect(mapStateToProps)(ThirdComponent);
Edit #2
As a followup to your other comment:
so passing value in props to components or use above said approach, Idk which is recommended ?
Avoid connecting components when you can and pass down the props to the children, the main reason for this is to prevent dependency on redux
.
I prefer keep my components "dumb" as i can and let them concern only on how things should look.
I do have some components that concern on how things should work and these components are mainly dealing with logic and passing down data to the children, they are the components i often connect.
When i notice that my app is scaling and some of my components are acting as a proxy of props (i even got a word for that! "Propxy"), that is they get props from their parent and pass them down without using them, i usually inject a connected component in the middle of the components tree so i can let the "propxy" components down the tree flow be more lighten and slim.
The generic approach of using redux
in react applications is use it along with react-redux
library. That library provides connect
function, which helps to access store in react components in more clean way.
Instead of trying to access store via context, just use connect
function:
import { connect } from 'react-redux';
const SecondComponent = ({ score }) => <div>{score}</div>
// with help of `connect`, you are providing `score` prop to `SomeComponent`
// next, you can render that connected component anywhere in your app
export default connect(
(state) => ({
score: state.score
})
)(SecondComponent)
You could use connect for any of your react components such as ThirdComponent
ad so on.
react-redux
tutorials for that. – lilezek Commented Oct 17, 2017 at 19:01state
in your component. The reason for using Redux andmapStateToProps
is to use props in yourrender
. – mhatch Commented Oct 17, 2017 at 19:04