Connect not working with StateLess component in Redux-react - javascript

I'm dispatching an action from some-other component , and store is getting updated with svgArr property, but though the following Stateless component connect'ed to the store , it ain't getting updated when store changes for svgArr.
Is it how it suppose to behave as it's a stateless component ? Or am I doing something wrong ?
const Layer = (props) => {
console.log(props.svgArr);
return (<div style = {
{
width: props.canvasWidth,
height: props.canvasWidth
}
}
className = {
styles.imgLayer
} > hi < /div>);
};
connect((state) => {
return {
svgArr: state.svgArr
};
}, Layer);
export default Layer;

You seem to be exporting Layer instead of the connected version of the Layer component.
If you look at the redux documentation: https://github.com/reactjs/react-redux/blob/master/docs/api.md#inject-dispatch-and-todos
It should be something like
function mapStateToProps(state) {
return {svgArr: state.svgArr}
}
export default connect(mapSTateToProps)(Layer)

Here's a rewrite of your code
import {connect} from 'react-redux';
// this should probably not be a free variable
const styles = {imgLayer: '???'};
const _Layer = ({canvasWidth}) => (
<div className={styles.imgLayer}
style={{
width: canvasWidth,
height: canvasWidth
}}
children="hi" />
);
const Layer = connect(
state => ({
svgArr: state.svgArr
})
)(_Layer);
export default Layer;

If you want to connect the stateless function you should wrap it into
the another const:
const Layer = (props) => {
return (
<div >
</div>
);
};
export const ConnectedLayer = connect(mapStateToProps)(Layer);

Here use redux with functional component in react native
import { useSelector } from 'react-redux';
const variable = useSelector(state => state.user.variable)

In addition, you can also pass multiple state object with functional components.
import {connect} from 'react-redux';
const PartialReview = ({auth, productreview}) => (
<div className="row">
<h2>{auth.uInfo._ubase}<h2>
<p>{productreview.review_description}
</div>
);
const mapStateToProps = (state) => {
return {auth: state.auth,productreview: state.productreview}
};
export default connect(mapStateToProps)(PartialReview)

Related

I structured my HOC so it could be invoked twice. How do I connect redux in this context

I structured my HOC so it could be invoked twice "functional programming". Now I'm failing to connect redux to get state and some functions. Please help how do I connect redux in this context. Everything I have tried has resulted in an error being thrown.
import React from "react"
export default (WrappedComponent) => {
return (mapFunctions) => {
return function({ ...props }) {
const [open, setOpen] = React.useState(false);
// typical functionality of the HOC
//search function
const handleSearch = (e) => {
let filter,
table,
tableRow,
tableCells,
txtValue,
results = [];
filter = e.currentTarget.value.toLowerCase();
table = document.querySelector(`#${mapFunctions.tableID}`);
tableRow = table.getElementsByTagName("tr");
Array.from(tableRow).forEach((row, index) => {
tableCells = row.getElementsByTagName("td")[1];
if (tableCells) {
txtValue = tableCells.textContent || tableCells.innerText;
if (txtValue.toLowerCase().indexOf(filter) > -1) {
return mapFunctions.searchFuncReasult === "array" ?
results.push(row) :
(tableRow[index].style.display = "");
} else {
return mapFunctions.searchFuncReasult === "array" ?
results.push(row) :
(tableRow[index].style.display = "none");
}
}
});
};
return (
<WrappedComponent {...props} handleSearch={handleSearch} />
);
};
};
};
If you want to connect the wrapped component to redux within your Higher Order Component, then you can refactor your HOC to define an "inner" functional component that can then also be wrapped by the conenct Higher Order Component (Alternatively you could use react-redux's useDispatch and useSelector hooks in the component directly).
import React from "react"
export default (WrappedComponent) => (mapFunctions) => {
const component = (props) => { // <-- will contain inject props from Redux
const [open, setOpen] = React.useState(false);
// typical functionality of the HOC
//search function
const handleSearch = (e) => {
let filter,
table,
tableRow,
tableCells,
txtValue,
results = [];
filter = e.currentTarget.value.toLowerCase();
table = document.querySelector(`#${mapFunctions.tableID}`);
tableRow = table.getElementsByTagName("tr");
Array.from(tableRow).forEach((row, index) => {
tableCells = row.getElementsByTagName("td")[1];
if (tableCells) {
txtValue = tableCells.textContent || tableCells.innerText;
if (txtValue.toLowerCase().indexOf(filter) > -1) {
return mapFunctions.searchFuncReasult === "array"
? results.push(row)
: (tableRow[index].style.display = "");
} else {
return mapFunctions.searchFuncReasult === "array"
? results.push(row)
: (tableRow[index].style.display = "none");
}
}
});
};
return <WrappedComponent {...props} handleSearch={handleSearch} />;
};
const mapStateToProps = (state) => ({
// ... any redux state selectors
});
const mapDispatchToProps = {
// ... any redux action creators
};
return connect(mapStateToProps, mapDispatchToProps)(component);
};
Another common pattern I use when combining several HOCs to decorate a component is to compose them together. If you are using react-redux then you likely are already using redux as a dependency, which exports such a compose utility. You likely already used it to compose all your reducers into a single root reducer. In my opinion this is the simpler solution, especially since it doesn't appear you actually need the injected redux props in your HOC wrapper.
import { compose } from 'redux';
...
export default compose(
connect(mapStateToProps, mapDispatchToProps),
YourCustomHOC
)(ComponentYouWantToWrap)(customMapFunctions);
If you invert the order of the arguments to your HOC
export default (mapFunctions) => (WrappedComponent) => {
then you can simplify the composition a bit
export default compose(
connect(mapStateToProps, mapDispatchToProps),
YourCustomHOC(customMapFunctions),
)(ComponentYouWantToWrap);

React: How to use one variable in one component when it is imported to another component

import React, { useEffect, useState } from 'react';
import { Card } from 'components/Card';
import { dateFilter } from 'helpers';
import Chart from 'chart.js';
import 'chartjs-chart-matrix';
import chroma from 'chroma-js';
import moment from 'moment';
const WeeklyTrafficCard = (props) => {
const { start, end, data, store } = props;
const capacity = store && store.capacity;
var numberOfweeks = 0; //representing how many weeks back
const dateArray = [];
var today = moment();
while (numberOfweeks < 10) {
var from_date = today.startOf('week').format('MM/DD/YY');
var to_date = today.endOf('week').format('MM/DD/YY');
var range = from_date.concat(' ','-',' ',to_date);
dateArray.push(range);
today = today.subtract(7, 'days');
numberOfweeks++;
//console.log(dateArray);
}
const [each_daterange, setDateRange] = useState();
I have this Component called WeeklyTrafficCard and I want to use the variable, each_daterange, in another component, which imported WeeklyTrafficCard as below to send the get request, clearly I cannot use each_daterange directly right here, how I can work around it?
import React, { useContext, useEffect, useState } from 'react';
import { WeeklyTrafficCard } from './WeeklyTrafficCard';
import { AppContext } from 'contexts/App';
import { API_URL } from 'constants/index.js';
import { todayOpen, todayClose } from 'helpers';
import moment from 'moment';
const WeeklyTrafficCardContainer = (props) => {
const { API } = useContext(AppContext);
const { store = {} } = props;
const [data, setData] = useState([]);
const open = todayOpen(store.hours, store.timezone);
const close = todayClose(store.hours, store.timezone);
useEffect(() => {
async function fetchData() {
const result = await API.get(`${API_URL}/api/aggregates`, {
params: {
each_daterange,
every: '1h',
hourStart: 13,
hourStop: 4
},
});
You should use a useEffect(prop drilling) to pass your variable in your parent:
import React, { Component } from "react";
import { render } from "react-dom";
import "./style.css";
const App = () => {
const [myVar, setMyVar] = React.useState('');
return (
<div>
<Child setMyVar={setMyVar} />
{myVar}
</div>
);
};
const Child = ({setMyVar}) => {
const myChildVar = "Hello world !"
React.useEffect( () => setMyVar(myChildVar),[]);
return <div> This is the child</div>
}
render(<App />, document.getElementById("root"));
Here is the repro on stackblitz
Understanding of the Problem
You want to pass data up to the parent from the child.
Manage each_daterange in the parent:
Instead of creating your useState variable each_daterange in the child you can declare it in the parent and pass down it's setter function. For instance:
const WeeklyTrafficCardContainer = (props) => {
const [eachDateRange, setEachDateRange] = useState();
return (
<div>
{/* your return */}
<WeeklyTrafficCard setEachDateRange={setEachDateRange} />
</div>
)
}
If you need to display eachDateRange in the traffic card, or the traffic card needs to completely own that variable, you can create another state variable in the parent and pass a callback to the child (essentially what is above but now you have two different state variables).
The parent becomes
const WeeklyTrafficCardContainer = (props) => {
const [requestDateRange, setRequestDateRange] = useState();
const updateRequestDateRange = (dateRange) => {
setRequestDateRange(dateRange)
}
return (
<div>
{/* your return */}
<WeeklyTrafficCard updateDateRange={updateRequestDateRange} />
</div>
)
}
Then in your WeeklyTrafficCard call props.updateDateRange and pass it the date range whenever each_daterange changes.
Ciao, of course you need a global state manager. My preferred is react-redux. In few word, react-redux allows you to have a state that is shared in all your components. Sharing each_daterange between WeeklyTrafficCardContainer and WeeklyTrafficCard will be very easy if you decide to use it.
This is the more appropriate guide to quick start with react-redux. have a nice coding :)
Keep the value outside of the component, where both can access it. There are other ways to do this, but just as a simple example you could create a simple "store" to hold it and reference that store from each component that needs it:
class Store {
setDateRange (newDateRange) {
this._dateRange = newDateRange;
}
get dateRange () {
return this._dateRange;
}
}
export default new Store(); // singleton; everyone gets the same instance
import store from './Store';
const WeeklyTrafficCard = (props) => {
// use current dateRange value
const dateRange = store.dateRange;
// set new dateRange
store.setDateRange( newDateRange );
// do other stuff
}
import store from './Store';
const WeeklyTrafficCardContainer = (props) => {
// use current dateRange value
const dateRange = store.dateRange;
// set new dateRange
store.setDateRange( newDateRange );
// do other stuff
}
If you want store updates to trigger component re-renders you'd need to add some higher order component plumbing, like redux's connect, or some other mechanism for triggering updates:
// pseudocode; make store an event emitter and return
// a component that re-renders on store events
store.connect = Component => {
return props => {
React.useEffect(() => {
store.addEventListener( ... )
return () => store.removeEventListener( ... )
})
}
}
Or if the components share a common parent, you could lift the state to the parent and pass the information to each component as props. If either component updates the value, the parent state change will trigger a re-render of both components with the new value:
const Parent = () => {
const [dateRange, setDateRange] = React.useState();
return (
<>
<WeeklyTrafficCardContainer
dateRange={dateRange}
onDateRangeChange={newRange => setDateRange(newRange)}
/>
<WeeklyTrafficCard
dateRange={dateRange}
onDateRangeChange={newRange => setDateRange(newRange)}
/>
</>
);
}
Let's rephrase the objective here.
Objective: access each_daterange from WeeklyTrafficCard component in WeeklyTrafficCardContainer component.
Note: simply put, choose the following case based on your problem.
choose using prop if the variable is to be accessed by only one component
choose using context if the variable is to be accessed by more than one components
Solution Cases:
Case A: using prop.
Case A.1. WeeklyTrafficCard is the parent of WeeklyTrafficCardContainer
each_datarange being passed from WeeklyTrafficCard component as prop to WeeklyTrafficCardContainer component
working example for reference: codesandbox - variable passed as prop
// WeeklyTrafficCard.jsx file
const WeeklyTrafficCard = () => {
const [each_daterange, setDateRange] = useState();
return (
<>
...
<WeeklyTrafficCardContainer eachDateRange={each_daterange} />
</>
);
};
// WeeklyTrafficCardContainer.jsx file
const WeeklyTrafficCardContainer = props => {
const eachDateRange = props.eachDateRange;
return (
<>
...
</>
);
};
Case A.2. WeeklyTrafficCard & WeeklyTrafficCardContainer are children of a parent, say WeeklyTraffic component
each_datarange will be present in WeeklyTraffic component which is shared among WeeklyTrafficCard component & WeeklyTrafficCardContainer component
// WeeklyTraffic.jsx file
const WeeklyTraffic = () => {
const [each_daterange, setDateRange] = useState();
return (
<>
...
<WeeklyTrafficCard eachDateRange={each_daterange} />
<WeeklyTrafficCardContainer eachDateRange={each_daterange} />
</>
);
};
// WeeklyTrafficCard.jsx file
const WeeklyTrafficCard = props => {
const eachDateRange = props.eachDateRange;
return (
<>
...
</>
);
};
// WeeklyTrafficCardContainer.jsx file
const WeeklyTrafficCardContainer = props => {
const eachDateRange = props.eachDateRange;
return (
<>
...
</>
);
};
Case B: using context.
follow blog example found: blog - react context
this is preferred way to implement if the variable/variables is/are shared or need to be accessed by more than 1 components

Timer React + Redux. React don't dispatch action by timer (SetInterval) in ComponentDidMount

I'm trying to make a timer in my App with React + Redux.
So I have a component parent:
import React, { Component } from "react";
import { connect } from "react-redux";
import { compose } from "redux";
import QuestionCounter from "../question-counter";
import FinishButton from "../finish-button";
import TimeCounter from "../time-counter";
import PauseButton from "../pause-button";
import testFinished from "../../actions/test-finished";
import timerTick from "../../actions/timer-tick";
import setTimer from "../../actions/set-timer";
import totalWithEwStruct from "../hoc/total-with-ew-structure";
import withIndicators from "../hoc/with-indicators";
const Total = ({ total, testFinished }) => {
const { finishedCount, totalCount, isPaussed, timeLeft } = total;
return (
<div className="test-total">
<QuestionCounter
finishedCount={finishedCount}
totalCount={totalCount}
testFinished={testFinished}
/>
<FinishButton testFinished={testFinished} />
<TimeCounter
timeLeft={timeLeft}
testFinished={testFinished}
setTimer={setTimer}
timerTick={timerTick}
/>
<PauseButton isPaussed={isPaussed} />
</div>
);
};
const mapStateToProps = ({ total, loading, error }) => {
return { total, loading, error };
};
const mapDispatchToProps = {
testFinished,
setTimer,
timerTick
}
export default compose(
totalWithEwStruct(),
connect(mapStateToProps, mapDispatchToProps),
withIndicators()
)(Total);
I try use timerTick by timer in componentDidMount
import React, { Component } from "react";
export default class TimeCounter extends Component {
componentDidMount() {
const { setTimer, timerTick } = this.props;
let timer = setInterval(() => {
timerTick();
console.log("tick");
}, 1000);
setTimer(timer);
}
componentDidUpdate() {
const { timeLeft, testFinished } = this.props;
if (timeLeft <= 0) {
testFinished();
}
}
render() {
const { timeLeft } = this.props;
return (
<div className="question-counter__timeleft">
Времени осталось
<span className="question-counter__timer">{timeLeft}</span>
</div>
);
}
}
So I see "tick" - "tick" - "tick" in console, but React doesn't dispatch my timerTick() function to reducer.
I have tried log to console action.type for debugging, and there is no action of timerTick.
const timerTick = () => {
return {
type: "TIMER_TICK"
};
};
export default timerTick;
Its code of action.
I don't understand why it doesn't work.
Your Total component needs to take timerTick function from props which is the one that is linked with redux store as you have added it to mapDispatchToProps.
If you do not destructure it from props, the ccomponent will use the imported function which isn't an action created unless its passed to dispatch function
const Total = ({ total, testFinished }) => {
const { finishedCount, totalCount, isPaussed, timeLeft, timerTick } = total;
return (
<div className="test-total">
<QuestionCounter
finishedCount={finishedCount}
totalCount={totalCount}
testFinished={testFinished}
/>
<FinishButton testFinished={testFinished} />
<TimeCounter
timeLeft={timeLeft}
testFinished={testFinished}
setTimer={setTimer}
timerTick={timerTick}
/>
<PauseButton isPaussed={isPaussed} />
</div>
);
};
You need to add dispatch of timer tick inside timer tick component. Because child component not aware about the actions.
Please refer below link for more details:
https://itnext.io/dispatching-actions-from-child-components-bd292a51f176
Response
if your component is not connected to redux you won’t be able to dispatch any action.
What do I mean?
Example
import React from “react”;
import { connect } from “react-redux”;
class MyCom extensa React.Component {
componentDidMount () {
const { action } = this.props;
action();
}
render () {
.....
}
}
const toState = state => ({....});
const toDispatch = {
action
};
export default connect(toState, toDispatch)(MyCom);
Explains
Basically connect from ”react-redux” is a HOC a high order component that on javascript world: is none but a high order function. a function that return another function.

Reactjs, reducers, language switching

I have just taken over a new reactjs project -- and I am trying to review how language switching has been invoked.
so like there are two links in the footer to do this language switch.
//footer.js
import React from 'react'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { selectLanguage, getLangDetails } from '../../actions/action_language'
import langObject from './Footer.lang'
class Footer extends React.Component {
constructor (props) {
super(props)
this.changeLanguageToGerman = this.changeLanguageToGerman.bind(this)
this.changeLanguageToEnglish = this.changeLanguageToEnglish.bind(this)
}
changeLanguageToGerman () {
this.props.selectLanguage('de')
}
changeLanguageToEnglish () {
this.props.selectLanguage('en')
}
render () {
let activeLang = 'language--active'
let alternativeLang = 'language--hover'
const lang = getLangDetails(this.props.active_language, langObject)
return (
<div>
<footer className='main-footer show-for-medium-only'>
<div className='medium-15 columns'>
<p className='text--white grid__row--offset--15 footer-text'>
<Link to={this.props.deURL} className={`text--white footer-text ${this.props.active_language === 'de' ? activeLang : alternativeLang}`} onClick={this.changeLanguageToGerman}>DE</Link>
|
<Link to={this.props.enURL} className={`text--white footer-text ${this.props.active_language === 'en' ? activeLang : alternativeLang}`} onClick={this.changeLanguageToEnglish}>EN</Link>
</p>
</div>
</footer>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
active_language: state.active_language
}
}
function mapDispatchToProps (dispatch) {
return bindActionCreators({selectLanguage: selectLanguage}, dispatch)
}
const { string, func } = React.PropTypes
Footer.propTypes = {
deURL: string,
enURL: string,
selectLanguage: func,
active_language: string
}
export default connect(mapStateToProps, mapDispatchToProps)(Footer)
// header.js
import React from 'react'
import { connect } from 'react-redux'
import { getLangDetails } from '../../actions/action_language'
import langObject from './Header.lang'
class Header extends React.Component {
render () {
let transparent
transparent = this.props.transparent ? 'transparent' : ''
const lang = getLangDetails(this.props.active_language, langObject)
return (
<div>
<header className={` main_headerbar__landing transition show-for-large-up ${transparent} `}>
<div className='contain-to-grid'>
{lang}
</div>
</header>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
active_language: state.active_language
}
}
const { bool, string } = React.PropTypes
Header.propTypes = {
transparent: bool,
active_language: string
}
export default connect(mapStateToProps)(Header)
--- so these are the header/footer components - and each has a json file that splits into an array of lang.
there is a file that looks like some global js that I think hooks into this - but I am struggling to extend this functionality into the rest of the site components/pages
//action_language.js
export const LANGUAGE_SELECTED = 'LANGUAGE_SELECTED'
export function selectLanguage (language) {
return {
type: LANGUAGE_SELECTED,
payload: language
}
}
export function getLangDetails (language = 'de', langObject) {
const langData = langObject.langs.filter((langVar) => langVar.lang === language)
return langData['0'].lines
}
ok - so here is the first page -- called services. Now what throws me first here is rather than use active_language its now just language.
//services.js
import React from 'react'
import Header from '../HeaderLanding/Header'
import Footer from '../Footer/Footer'
import NoBundle from './NoBundle'
import HowTiles from './HowTiles'
import CarouselTiles from './CarouselTiles'
import YourAdvantages from './YourAdvantages'
import InformationTiles from './InformationTiles'
import ContactTiles from './ContactTiles'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { selectLanguage, getLangDetails } from '../../actions/action_language'
// language file
import langObject from './services.lang.json'
// services css
import './services.css'
// getting the distinct URLs from the lang files
const deURL = langObject.langs[0].pageURL
const enURL = langObject.langs[1].pageURL
const Spacers = () => (
<div>
<div className='row show-for-large-up' style={{ height: '250px' }} />
<div className='row show-for-medium-only' style={{ height: '150px' }} />
<div className='row show-for-small-only' style={{ height: '80px' }} />
</div>
)
class Services extends React.Component {
constructor (props) {
super(props)
this.language = props.match.params.langURL
}
componentWillMount () {
document.getElementById('body').className = 'overlay-background-services'
this.updateLanguage()
}
updateLanguage () {
console.log('updatelang', this.language)
if (this.language === 'de' || !this.language) {
this.props.selectLanguage('de')
} else {
this.props.selectLanguage('en')
}
}
componentWillUnmount () {
document.getElementById('body').className = ''
}
render () {
const lang = getLangDetails(this.language, langObject)
return (
<div>
<Header transparent />
<Spacers />
<NoBundle lang={lang} />
<HowTiles />
<CarouselTiles />
<YourAdvantages />
<InformationTiles />
<ContactTiles />
<Footer deURL={deURL} enURL={enURL} />
</div>
)
}
}
const mapStateToProps = (state) => {
return {
language: state.language
}
}
function mapDispatchToProps (dispatch) {
return bindActionCreators({selectLanguage: selectLanguage}, dispatch)
}
const { func, string, object } = React.PropTypes
Services.propTypes = {
selectLanguage: func,
langURL: string,
params: object,
match: object
}
export default connect(mapStateToProps, mapDispatchToProps)(Services)
The Footer component deals with setting the current language by invoking the Redux action creator selectLanguage. Essentially this dispatches an action (you can think of this as a custom event with some corresponding data - the language) to the store that will persist the user's language selection for use elsewhere.
In order to consume the language in other components, that language selection needs to be passed into the component (in this case the Header) from the Redux store.
This is the code of interest in header that does that...
const mapStateToProps = (state) => {
return {
active_language: state.active_language
}
}
export default connect(mapStateToProps)(Header)
Here you are connecting the Header to the store, with a function that describes how the store should map values into props on your react component. state.active_language is where the language that the user has selected is stored, and this is telling it to be passed as a prop called active_language on your Header component
The connect function is a decorator that will create what's know as a Higher Order Component (HOC) which is essentially a component with props or functionality automatically injected into it (decorated in this case with an automatically passed value for the active_language prop from the store)
You can do the same for any other component that need this language setting, or go a step or two further
Instead of passing the active language name, pass the corresponding language itself...
import { getLangDetails } from '../../actions/action_language'
import langObject from './Header.lang'
const mapStateToProps = (state) => {
return {
active_language: getLangDetails(state.active_language, langObject)
}
}
export default connect(mapStateToProps)(Header)
OR better yet write another HOC that wraps any component you pass with this info...
import { getLangDetails } from '../../actions/action_language'
export default const injectLanguage = (component, langObject) => connect((state) => ({
language: getLangDetails(state.active_language, langObject)
})
)(component)
Then in subsequent components with a language prop, decorate with this
import injectLanguage from './some/where'
import langObject from './MyLanguageDetailsAwareComponent.lang'
class MyLanguageDetailsAwareComponent extends React.Component {
render() {
return this.props.language
}
}
export default injectLanguage(MyLanguageDetailsAwareComponent, langObject)

How to pass state to more then one component in redux

I start working with React + Redux and newbie to the framework.*
What is am trying to do?
I have to click a button and on the click it will show an svg path in other container/svg tag.
My code or my code
import { connect } from "react-redux";
import { BodyTemplate, Button } from "../component/svgPreview/Preview.jsx";
import { previewBodyTemplate } from "../modcon/Actions.js";
const mapStateToProps = ({ previewTemplateState }) => {
return ({
previewTemplateState: previewTemplateState
});
};
const mapDispatchToProps = (dispatch) => {
return ({
onImageClick: (value) => {
dispatch(previewBodyTemplate(value));
}
});
};
/* the following code will work because we cannot export more then one by
default **/
/*
const PreviewContainer = connect(mapStateToProps, mapDispatchToProps)(Button);
const PreviewBody = connect(mapStateToProps, mapDispatchToProps)(BodyTemplate);
export default PreviewContainer;
export default PreviewBody;
*/
/* so i try this */
export const PreviewContainer = connect(mapStateToProps, mapDispatchToProps)(Button);
export const PreviewBody = connect(mapStateToProps)(BodyTemplate);
According to my knowlage i am passing the state to two components so when the state of one update it will update the other.
But the file is not working because we and not export it directly.
How i have to tackle to pass the state to more then one components
below is the error when i am exporting directly
*
You need to create a parent component, this component will contain the button and the preview component.
const MyContainer = ({ image, onImageClick }) => (
<div>
<div className="sidebar">
<Button label="Preview image" onClick={onImageClick} />
</div>
<div className="content">
<Preview source={image} />
</div>
</div>
);
Once you have your container ready, you need to map the props of this component to the state/actions from redux.
const mapStateToProps = ({ image, previewTemplateState }) => {
return ({
image: image,
previewTemplateState: previewTemplateState
});
};
const mapDispatchToProps = (dispatch) => {
return ({
onImageClick: (value) => {
dispatch(previewBodyTemplate(value));
}
});
};
export default connect(mapStateToProps, mapDispatchToProps)(MyContainer);
Now the main container will receive the data and the actions, from there you can send whatever you need to the children components.
The button and the preview image component are stateless component, they just receive props from the parent container.

Categories