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 ?
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.
You just need to export the store from the module where it created with createStore() . Also, it shouldn't pollute the global window object.
As with several other questions, it is possible to create multiple distinct Redux stores in a page, but the intended pattern is to have only a single store. Having a single store enables using the Redux DevTools, makes persisting and rehydrating data simpler, and simplifies the subscription logic.
Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state. Using local component state is fine.
Any 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With