How to extract arrays in a state through React.createContext ();? - javascript

how to extract arrays in a state through React.createContext();
This is my state
constructor(props){
super(props)
this.state = {
sideDrawerOpen: false,
resultData:[
{id:"1",desc:"Dining",img:dining},
{id:"2",desc:"Wellness",img:wellness},
{id:"3",desc:"Activities",img:activities},
{id:"4",desc:"Dining",img:dining},
{id:"5",desc:"Wellness",img:wellness},
{id:"6",desc:"Activities",img:activities},
{id:"7",desc:"Activities",img:activities}
],
title:"lorem"
}
}
This is MyContext.provider
return (
<MyContext.Provider value={this.state}>
<Toolbar click={this.drawerButtonClickHandler} />
{sideDrawer}
{backdrop}
<Banner />
<HomeMenu data={this.state} />
<Merchants />
<Voucher />
<br />
</MyContext.Provider>
)
I tried looping but it didn't work but if I release data from a state that isn't an array I can do it.
class HomeMenu extends Component{
render(){
return(
<MyContext.Consumer>
{(context) => (
<p>{context.title}</p>
)}
</MyContext.Consumer>
)
}
}

Related

Not able to access array passed as props from parent - React

Getting started with React. I have two drop-downs in the child component WeatherOptionsView. I'm trying to set it's default value based on the prop array of previously selected values passed from Parent component WeatherContainerView. I also want to set it to the state as the value will change onChange of dropdown going forward.
The UI blows up when I do this. When I print the values of props, I see that the selectedCodes is null. Where am I going wrong with this? Any help will be appreciated. Thanks!
console.log(this.props.isFailed); //false
console.log(this.props.selectedValues); //null
WeatherOptionsContainer.js
class WeatherOptionsContainer extends React.Component {
constructor(props) {
super(props);
this.state = { isFailed: true, isLoading: false, selectedValues: ['City1', 'City2']};
}
render() {
return (
<WeatherOptionsView
isFailed={this.state.isFailed}
isLoading={this.state.isLoading}
selectedValues={this.state.selectedValues}
/>
);
}
}
WeatherOptionsView.js
class WeatherOptionsView extends React.Component {
constructor(props) {
super(props);
this.state = { reasonState: false, selectedValues: this.props.selectedValues };
}
render() {
const cx = classNames.bind(styles);
return (
<ContentContainer fill>
<Spacer marginTop="none" marginBottom="large+1" marginLeft="none" marginRight="none" paddingTop="large+2" paddingBottom="none" paddingLeft="large+2" paddingRight="large+2">
<Fieldset legend="City">
<Grid>
<Grid.Row>
<Grid.Column tiny={3}>
<SelectField selectId="State1" required placeholder="Select" label={["City:"]} error={["Error message"]} isInvalid={this.state.reasonState} defaultValue={this.props.selectedValues[0]}>
<Select.Option value="City1" display="City1" />
<Select.Option value="City2" display="City2" />
</SelectField>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column tiny={3}>
<SelectField selectId="State2" required placeholder="Select" label={["City:"]} error={["Error message"]} isInvalid={this.state.reasonState} defaultValue={this.props.selectedValues[1]}>
<Select.Option value="City1" display="City1" />
<Select.Option value="City2" display="City2" />
</SelectField>
</Grid.Column>
</Grid.Row>
</Grid>
)}
/>
</ContentContainer>
);
}
}
The issue is, you are passing the prop selectedCodes and in the inner component you are using this.props.selectedValues. This should work.
constructor(props) {
super(props);
this.state = { reasonState: false, selectedValues: this.props.selectedCodes };
}

Unable to send the updated value of state through props in react js

I am trying to send state value from parent to child component.Initially the state value is empty.After an API call,state value get updated but my props is taking the initial empty value.
class Metrics extends React.Component {
constructor(props) {
super(props);
this.state.result:[];
}
submit = e => {
e.preventDefault();
var URL =
"http://localhost:8080/fetchAnalysisData;
this.setState({ formsubmit: true });
fetch(URL, {
method: "GET"
})
.then(res => res.json())
.then(data => {
console.log("Response Success!!");
this.setState({ result: data });
});
};
render(){
return(
<Button onClick={this.submit}
fontSize: "small",
marginLeft: "30%"
}}
>
VIEW RESULT
</Button>
<div className={this.state.formsubmit ? "showDisplay" : "hide"}>
<DipslayBarChart result={this.state.result}></DipslayBarChart>
</div>
)
}
Child Component:
class DipslayBarChart extends React.Component {
constructor(props){
super(props);
}
render(){
return(
<div>
<BarChart width={500} height={300} data={this.props.result}>
<XAxis dataKey="Date" />
<YAxis />
<Tooltip cursor={false} />
<Legend />
<Bar dataKey="Success" stackId="a" fill="#068f12" label />
<Bar
dataKey="Failure"
stackId="a"
fill="#ec0b0b"
/>
</BarChart>
</div>
)
}
}
How to update the prop value once the state is updated?
Write your constructor like this,
constructor(props) {
super(props);
this.state={
result:[]
}
}
Moreover If you are not using the props in the constructor no need to declare constructor. you can declare state like this
state={
result:[]
}

How to pass data from render method to multiple components in React?

I am new to React so looking like how can I render the data of image, name and user name from render method of one component to other components.
class Avatar extends React.Component {
render() {
return (
<img src={''} />
)
}
}
class Label extends React.Component {
render() {
return (
<h1>Name: </h1>
)
}
}
class ScreenName extends React.Component {
render() {
return (
<h3>Username: </h3>
)
}
}
class Badge extends React.Component {
render() {
return (
<div>
<Avatar />
<Label />
<ScreenName />
</div>
)
}
}
And the render method is this. How to read this image username and name into other components and update the view. Tried using {this.props.name} and also {this.props.user.name} but I am getting name as undefined.
ReactDOM.render(
<Badge user={{
name: 'Tyler McGinnis',
img: 'https://avatars0.githubusercontent.com/u/2933430?v=3&s=460',
username: 'tylermcginnis'
}} />,
document.getElementById('app')
);
And the HTML is this
<div id='app'></div>
You pass data via the component's props. It looks like this:
class Avatar extends React.Component {
render() {
return (
<img src={this.props.img} />
)
}
}
class Label extends React.Component {
render() {
return (
<h1>{this.props.name}</h1>
)
}
}
class ScreenName extends React.Component {
render() {
return (
<h3>{this.props.username}</h3>
)
}
}
class Badge extends React.Component {
render() {
return (
<div>
<Avatar img={this.props.user.img}/>
<Label name={this.props.user.name} />
<ScreenName username={this.props.user.username} />
</div>
)
}
}
And after some refactoring, you end up with this:
const Avatar = ({img}) => (
<img src={img} />
);
const Label = ({name}) => (
<h1>{name}</h1>
);
const ScreenName = ({username}) => {
<h3>{username}</h3>
);
const Badge = ({user}) => (
<div>
<Avatar img={user.img}/>
<Label name={user.name} />
<ScreenName username={user.username} />
</div>
)
Note that here we made use of so called functional stateless components, which can make your code a lot shorter and often more elegant. See here.
You can pass the data via props
https://codesandbox.io/s/o4nz576jn5

How to show Data results on click in React?

I am trying to show my results from a JSON file only when the search button is clicked. What is the correct way to do it?
Right now as the user types a product the results are show. I have a simple filter, that is filtering the results, but I would like to make that only appear when the button is clicked. I only want to show results when the search button is clicked.
class App extends Component {
constructor(props){
super(props);
this.state = {
value: '',
list: []
}
this.handleChange = this.handleChange.bind(this);
this.handleSearch = this.handleSearch.bind(this);
this.refresh();
}
handleChange(event){
this.setState({ ...this.state, value: event.target.value })
}
refresh(){
axios.get(`${URL}`)
.then(resp => this.setState({...this.state, value: '', list: resp.data}));
}
handleSearch(product){
this.refresh();
}
render(){
return(
<div className="outer-wrapper">
<Header />
<main>
<Container>
<Row>
<Col xs={12} md={12} lg={12} className="pl-0 pr-0">
<SearchBar
handleChange={this.handleChange}
handleToggle={this.handleToggle}
handleSearch={this.handleSearch}
value={this.state.value}
/>
<SearchResultBar
value={this.state.value}
/>
<Filter />
</Col>
</Row>
<ProductList
value={this.state.value}
list={this.state.list}
/>
</Container>
</main>
</div>
)
}
}
export default App;
class Search extends Component {
constructor(props){
super(props);
}
render(){
return(
<div className="search-input">
<InputGroup>
<Input placeholder='Enter Search'
onChange={this.props.handleChange}
value={this.props.value}
/>
<InputGroupAddon className='input-group-append'
onClick={this.props.handleSearch}>
<span className='input-group-text'>
<i className="fa fa-search fa-lg fa-flip-horizontal"></i>
</span>
</InputGroupAddon>
</InputGroup>
</div>
)
}
}
export default Search;
class ProductList extends Component {
constructor(props){
super(props);
this.state = {
}
}
render(){
let filteredSearch = this.props.list.filter(
(product) => {
return product.title.indexOf(this.props.value) !== -1
}
)
return(
<Container>
<Row>
{
filteredSearch.map(item => {
return <Product {...item} key={item._id} />
})
}
</Row>
</Container>
);
}
}
export default ProductList;
As it stands, my list of products is being displayed in the app as soon as it loads. This seems something trivial, but I have been scratching my head in trying to solve it.
You're calling this.refresh() inside the constructor. So it gets run on mount.
Just remove it from the constructor and you should be fine.

Resetting state on component in React

I have a simple problem in React JS. I have two different click events, which switch the state of the component. The first one works perfectly, however I cannot get the second event to reset the component back to its original state. This is a stripped down version of my problem, so just know that I cannot move the click functions into the Child component.
class Parent extends Component{
constructor(){
this.state = {
open: false
}
this.handleOpen = this.handleOpen.bind(this)
this.handleClose = this.handleClose.bind(this)
}
handleOpen(){
this.setState({open: true})
}
handleClose(){
this.setState({open: false})
}
render(){
return(
<div>
<Child onOpen={this.handleOpen} onClose={this.handleClose} />
<Child onOpen={this.handleOpen} onClose={this.handleClose} />
<Child onOpen={this.handleOpen} onClose={this.handleClose} />
<Child onOpen={this.handleOpen} onClose={this.handleClose} />
</div>
)
}
}
Like I said, the handleOpen function switches the state, but the handleClose does not switch it back. I can get a console log to show on the handleClose function, so I know that it does not have to do with how it is being hooked up to the Child Component. Am I missing something about how to reset a state value after it has already been switched. Thank you for your help!
Here is How you have to do it!
class Child extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this.props.isOpen);
if (this.props.isOpen) {
this.props.onClose();
} else {
this.props.onOpen();
}
}
render() {
return <button onClick={this.handleClick}>Click ME</button>;
}
}
class Parent extends React.Component{
constructor(props){
super(props);
this.state = {
open: false
}
this.handleOpen = this.handleOpen.bind(this)
this.handleClose = this.handleClose.bind(this)
}
handleOpen(){
this.setState({open: true})
}
handleClose(){
this.setState({open: false})
}
render(){
return(
<div>
<p>{this.state.open.toString()}</p>
<Child onOpen={this.handleOpen} onClose={this.handleClose} isOpen={this.state.open} />
<Child onOpen={this.handleOpen} onClose={this.handleClose} isOpen={this.state.open} />
<Child onOpen={this.handleOpen} onClose={this.handleClose} isOpen={this.state.open} />
<Child onOpen={this.handleOpen} onClose={this.handleClose} isOpen={this.state.open} />
</div>
)
}
}
ReactDOM.render(
<Parent/>,
document.getElementById('container')
);

Categories