Set state like this props in react - react-redux

Hello i have this code
import React from 'react'
import Link from 'react-router/lib/Link'
import { connect } from "react-redux"
import { load } from '../../actions/customerActions'
import List from './list';
import MdAdd from 'react-icons/lib/md/add'
#connect(store => {
return {
customers: store.customer.customers
}
})
export default class Customer extends React.Component {
componentDidMount() {
this.props.dispatch(load({location:localStorage.getItem('locationb')}));
}
render() {
const { customers } = this.props;
const tea = customers.customers && customers.customers.map(customer => <List key={customer.profile} customer={customer} />) || [];
return(
<div class="container">
{ customers.customers ?
<div class="columns is-multiline mb-100">
{ tea }
</div>
: 'Não exitem Clientes'}
<Link to="/customer/create" class="button is-info btn-rounded" title="Novo"><MdAdd /></Link>
</div>
)
}
}
But i only have access to customers in render passing this props.
How can i pass customer to a state variable in component did mount or else ?
i mean customers const { customers } = this.props; how i make like this.setState({customers: customers}) Having in the beginning this.state(customers: [])

YOu can use
componentWillReceiveProps(newProps){
console.log(newProps.customers.customers)
this.setState({customers: newProps.customers.customers})
}
it works for me
thanks
Carlos Vieira

Related

How can I use text formatting (bold, italic, etc.) with i18n using Gatsby?

I'm using gatsby-plugin-react-i18next for translating my website, and it works with simple text. But when I try to format parts of the text, with bold text or italic text, it doesn't work (I don't know how to do it).
How can I format a specific part of a paragraph using i18n?
Below is an example of my setup.
page JS
const IndexPage = () => {
const { t } = useTranslation();
return (
<Layout>
<Seo title="Home" />
<div>
<h1>
{t("HomepageHeader")}
</h1>
<p>
{t("HomepageDescription")}
</p>
</div>
</Layout>
)
}
export default IndexPage
Folder structure:
locales
-en
--translation.json
-nl
--translation.json
Example JSON en
{
"HomepageHeader": "Grow your business with a modern website!",
"HomepageDescription": "Your website is the number 1 selling point, to your customers. Make sure you get the most out of it!"
}
How can I make for example only "number 1 selling point" in the HomepageDescription bold?
Have a look at the Trans Component: https://react.i18next.com/latest/trans-component
Or use a markdown component, something like:
import React from 'react';
import Markdown from './Markdown';
import { useTranslation } from '../utils';
export function Text({
i18nKey,
ns = 'client-locize-app-loaders',
i18nOptions = {},
message,
defaultValue,
linkTarget = '_blank',
}) {
const { t, ready } = useTranslation(ns, { useSuspense: false });
if (!ready)
return (
<Markdown source={message || 'loading...'} noContainer options={{ linkTarget: '_blank' }} />
);
return (
<Markdown
source={message || t(i18nKey, { defaultValue, ...i18nOptions })}
noContainer
options={{ linkTarget }}
/>
);
}
import React from 'react';
import { Remarkable } from 'remarkable';
export class Markdown extends React.Component {
constructor(props) {
super(props);
this.content = this.content.bind(this);
this.renderMarkdown = this.renderMarkdown.bind(this);
}
componentWillUpdate(nextProps, nextState) {
if (nextProps.options !== this.props.options) {
this.md = new Remarkable(nextProps.options);
}
}
content() {
if (this.props.source)
return <span dangerouslySetInnerHTML={{ __html: this.renderMarkdown(this.props.source) }} />;
return React.Children.map(this.props.children, (child) => {
if (typeof child === 'string') {
return <span dangerouslySetInnerHTML={{ __html: this.renderMarkdown(child) }} />;
}
return child;
});
}
renderMarkdown(source) {
if (!this.md) this.md = new Remarkable(this.props.options);
if (this.props.renderInline) return this.md.renderInline(source);
return this.md.render(source);
}
render() {
const Container = this.props.container;
if (this.props.noContainer) return this.content();
return (
<Container className={this.props.className} style={this.props.style}>
{this.content()}
</Container>
);
}
}
Markdown.defaultProps = {
noContainer: false,
renderInline: false,
container: 'div',
options: {},
className: '',
};

mapDispatchToProps not updating store

I'm working on a personal project with redux. My mapStateToProps function seems to me properly written. but when I try to use it to send an object to my store nothing works.
Here's my function:
const mapDispatchToProps = dispatch => {
return {
addOrder: (item) => {
dispatch(addOrder(item));
}
}
}
<div className="recordOrder">
<button onclick={() => this.props.addOrder(this.state)}>Enregistrer et lancer la commande</button>
</div>
And my reducer:
const initialState = {
orderList : []
}
console.log(initialState);
export default function rootReducer ( state= initialState, action){
const orderList = [...state.orderList];
let position
switch (action.type){
case ADD_ORDER:
return {
orderList : [...state.orderList, action.payload]
};
case DELETE_ORDER:
position = orderList.indexOf(action.payload)
orderList.splice(position, 1)
return {
orderList
}
default:
return state;
}
console.log(state)
}
My entire component as requested:
import React, { Component } from 'react';
import { NavItem } from 'react-bootstrap';
import menu from './menu';
import { connect } from 'react-redux';
import { addOrder} from '../action'
class getOrder extends Component {
state = {
number: `CMD-${Date.now()}`,
order:[],
total: 0 ,
menu:menu,
isPaid: false
}
addItem = (index) => {
const order = [...this.state.order];
const menu = [...this.state.menu];
let total = this.state.total;
const pizza = menu[index];
console.log(pizza);
let ind = order.findIndex((item) =>
item.article == pizza.name
)
if (ind === -1){
order.push({article: pizza.name, price: pizza.price, volume:1})
total = total + order[order.length-1].price
} else if (ind != -1){
order[ind].volume++
total = total + order[ind].price
}
this.setState({
order:order,
total:total
})
console.log("youpiii");
console.log(this.state.total);
console.log(this.state.order);
}
render() {
const menuDisplay= menu.map( (item) => {
return (
<div>
<img onClick={() => this.addItem(item.number)} src={`${process.env.PUBLIC_URL}${item.picture}`} alt="picture" />
<div className="tagPrice">
<p>{item.name}</p>
<p>{item.price} €</p>
</div>
</div>
)
});
const currentOrder = [...this.state.order]
const orderDisplay = currentOrder.map((item) => {
let price = item.price*item.volume;
console.log(price);
return (
<div>
<h1>{item.volume} × {item.article}</h1>
<p>{price} €</p>
</div>
)
} );
return (
<div className="takeOrder">
<div className="orderban">
<h1>Pizza Reflex</h1>
</div>
<div>
<div className="menuDisplay">
{menuDisplay}
</div>
<div className="orderBoard">
<h1>Détail de la commande N°{this.state.number}</h1>
{orderDisplay}
<div className="total">
<h2>Soit un total de {this.state.total} € </h2>
</div>
<div className="recordOrder">
<button onclick={() => this.props.addOrder(this.state)}>Enregistrer et lancer la commande</button>
</div>
</div>
</div>
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return {
addOrder: (item) => {
dispatch(addOrder(item));
}
}
}
export default connect ( mapDispatchToProps) (getOrder);
Can someone tell me what I've missed ?
Thanks for your help !
What you are missing is more of your code it can not be solved with what you have.
In more details what I need is the this.state , combinedReducer
The easiest fix you can do now is changing yow mapDispatchToProps works better if it is an obj
const mapStateToProps = (state) => {
return {
// here you specified the properties you want to pass yow component fom the state
}
};
const mapDispatchToProps = {action1, action2};
export default connect ( mapDispatchToProps) (getOrder);
connectreceives two params mapStateToProps and mapDispatchToProps,
mapDispatchToProps is optional, but mapStateToProps is mandatory, there for you need to specified, if your are not going to pass anything you need to pass a null value
export default connect (null, mapDispatchToProps) (getOrder);
also avoid exporting components without a name
example
function MyButton () {}
const MyButtonConnect = connect(state, dispatch)(MyButton);
export default MyButtonConnect

How to pass props to child component from parent component and receive it in child component using react-redux

My Parent component is like - Requestdetails component
import React, { Component } from "react";
import TopBarComponent from '../../common/TopBar/topBar'
export default class RequestDetailsComponent extends Component {
showBreadcrumb: boolean;
breadcrumbs: { title: string; navigate: string; state: boolean; }[];
constructor(props: any) {
super(props)
this.showBreadcrumb = true;
this.breadcrumbs = [
{ title: 'Dashboard', navigate: 'dashboard', state: true },
{ title: 'Requests', navigate: 'requestList', state: true },
{ title: 'Request Details', navigate: '', state: false }]
}
render() {
return (
<div>
<TopBarComponent showBreadcrumb={this.showBreadcrumb} breadcrumbs={this.breadcrumbs}/>
</div>
);
}
}
Child component -- TopBar component
import React, { Component } from "react";
import { Breadcrumb, BreadcrumbItem } from 'carbon-components-react'
export default class TopBarComponent extends Component {
showBreadcrumb:boolean;
constructor(props:any){
super(props);
this.showBreadcrumb = props.showBreadcrumb
}
render() {
let breadcrumbClass = 'dte-breadcrumbs dte-breadcrumbs--with-layout';
if(this.showBreadcrumb){
return (
<div className={breadcrumbClass}>
<div className="dte-page-container">
<div className="container-fluid">
<Breadcrumb >
<BreadcrumbItem>
Breadcrumb 1
</BreadcrumbItem>
</Breadcrumb>
</div>
</div>
</div>
);
}
return null;
}
}
I want to pass 'showBreadcrumb' and 'breadcrumbs' array to topBar component from Requestdetails component. but unable to do it in react-redux.
The above approach i used to follow in react but now i'm trying this react-redux., but failed to pass.
Please advise how i can pass this.
Assuming you have your redux store and provider setup and configured correctly, the way to connect UI components to your redux store, believe it or not, is with react-redux's connect HOC.
import React, { Component } from "react";
import { connect } from 'react-redux'; // import the connect HOC
import { Breadcrumb, BreadcrumbItem } from "carbon-components-react";
class TopBarComponent extends Component {
render() {
let breadcrumbClass = "dte-breadcrumbs dte-breadcrumbs--with-layout";
if (this.props.showBreadcrumb) {
return (
<div className={breadcrumbClass}>
<div className="dte-page-container">
<div className="container-fluid">
<Breadcrumb>
<BreadcrumbItem>
Breadcrumb 1
</BreadcrumbItem>
</Breadcrumb>
</div>
</div>
</div>
);
}
return null;
}
}
// define a function that maps your redux state to props
const mapStateToProps = state => ({
breadcrumbs: state.breadcrumbs, // these should match how your reducers define your state shape
showBreadcrumb: state.showBreadcrumb,
});
// export the connected component
export default connect(mapStateToProps)(TopBarComponent);

Redux store error: <Provider> does not support changing `store` on the fly

I am trying to setup my first react/redux/rails app. I am using react_on_rails gem to pass in my current_user and gyms props.
Everything appears to work ok so far except my console shows error:
<Provider> does not support changing `store` on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions.
Googling gives me hints that this can happen if you try to create a store within a render method, which causes store to get recreated. I don't see that issue here. Where am I going wrong?
//App.js
import React from 'react';
import { Provider } from 'react-redux';
import configureStore from '../store/gymStore';
import Gym from '../components/Gym';
const App = props => (
<Provider store={configureStore(props)}>
<Gym />
</Provider>
);
export default App;
../store/gymStore.jsx
//the store creation.
/*
// my original way
import { createStore } from 'redux';
import gymReducer from '../reducers/';
const configureStore = railsProps => createStore(gymReducer, railsProps);
export default configureStore;
*/
/* possible fix: https://github.com/reactjs/react-redux/releases/tag/v2.0.0 */
/* but adding below does not resolve error */
import { createStore } from 'redux';
import rootReducer from '../reducers/index';
export default function configureStore(railsProps) {
const store = createStore(rootReducer, railsProps);
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept(() => {
const nextRootReducer = require('../reducers').default;
store.replaceReducer(nextRootReducer);
});
}
return store;
}
I am not sure my rendered component is necessary but in case it is:
//compenents/Gym.jsx
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import LeftMenu from './LeftMenu';
class Gym extends React.Component {
static propTypes = {
//name: PropTypes.string.isRequired // this is passed from the Rails view
};
/**
* #param props - Comes from your rails view.
*/
constructor(props) {
super(props);
this.state = {
current_user: this.props.current_user,
gyms: JSON.parse(this.props.gyms),
active_gym: 1, //JSON.parse(this.props.gyms)[0],
name: 'sean',
title: 'Gym Overview'
};
}
updateName = name => {
this.setState({ name });
};
isLoggedIn = () => {
if (this.state.current_user.id != '0') {
return <span className="text-success"> Logged In!</span>;
} else {
return <span className="text-danger"> Must Log In</span>;
}
};
isActive = id => {
if (this.state.active_gym == id) {
return 'text-success';
}
};
render() {
return (
<div className="content">
<h2 className="content-header">{this.state.title}</h2>
{LeftMenu()}
{this.state.current_user.id != '0' ? <span>Welcome </span> : ''}
{this.state.current_user.first_name}
<h3 className="content-header">Your Gyms</h3>
<ul>
{this.state.gyms.map((gym, key) => (
<li key={key} className={this.isActive(gym.id)}>
{gym.name}
</li>
))}
</ul>
{this.isLoggedIn()}
<hr />
{/*
<form>
<label htmlFor="name">Say hello to:</label>
<input
id="name"
type="text"
value={this.state.name}
onChange={e => this.updateName(e.target.value)}
/>
</form>
*/}
</div>
);
}
}
function mapStateToProps(state) {
return {
current_user: state.current_user,
gyms: state.gyms,
active_gym: state.active_gym
};
}
export default connect(mapStateToProps)(Gym);

relay refetch doesn't show the result

I'm trying to create a live search-result component(lazy load one). It works perfectly for the first time but refetch doesn't update the data. I see the request and respoonse in Network tab! so it does get the data, but it doesn't supply it to the component!
any idea why?
import React, { Component } from 'react';
import {
createRefetchContainer,
graphql,
} from 'react-relay';
import ProfileShow from './ProfileShow';
class ProfileList extends Component {
render() {
console.log("rendering....", this.props)
return (
<div className="row">
<input type="text" onClick={this._loadMe.bind(this)} />
{this.props.persons.map((person) => {
return (
<div className="col-md-3">
<ProfileShow person={person} />
</div>
);
})}
</div>
);
}
_loadMe(e) {
const refetchVariables = fragmentVariables => ({
queryStr: e.target.value,
});
this.props.relay.refetch(refetchVariables, null, (...data) => {
console.log(data)
});
}
}
const FragmentContainer = createRefetchContainer(
ProfileList,
{
persons: graphql.experimental`
fragment ProfileList_persons on Person #relay(plural: true) {
fullname
number
email
pic
}
`
},
graphql.experimental`
query ProfileListRefetchQuery($queryStr: String!) {
talentList(query: $queryStr) {
...ProfileList_persons
}
}
`,
);
export default FragmentContainer;

Resources