1

I'm sorry if the title doesn't explain much. I have a react component, which has a button and some texts, and I used it 3 times. I want each button to display its text when I click on it, but hide the other texts.

The code I've written makes me able to display the texts when I click on each button, but it doesn't hide the other buttons' texts. I can make 3 components, one for each button, but I want to try this method, and I'm not sure i can make the other one work too

React component:

import React from 'react'
export default class Button extends React.Component {
    state={
        display: 'none'
    }
    render() {
        return (<div>
            <button
                onClick={()=>this.setState({display:'block'})}
                style={{ width: "50px", height: "50px", display:"inline-block" }}>
                {this.props.children}
            </button>
            <h1 style={{display: this.state.display}}>
                {this.props.title}
            </h1>
            <img style={{display: this.state.display}} src={this.props.src} alt=""></img>
            <p style={{display: this.state.display}}>
                {this.props.descri}
            </p>
        </div>)
    }
}

App.js:

import React from 'react';
import './App.css';
import Button from './sarra.js';
import Aa from './Aa.jpg';
import kacem from './b1.jpg';
import harold from './kacem.JPG';
/*
const person = [
  {name:"sarah",
    imgsrc:"" ,
  description: "ipsum lorem " 
  },
  {name:"sarah",
    imgsrc:"" ,
  description: "ipsum lorem " 
  },
  {name:"sarah",
    imgsrc:"" ,
  description: "ipsum lorem " 
  }

]
*/
const isShown =() =>{
 Button.style="backgroundColor: red"
}
function App() {
  return (<div>
<Button title="Aa" descri="this is ali's profile" src={Aa} >ali</Button>

<Button title="harold" descri="this is harold's profile" src={harold} onClick={isShown()}>harold</Button>

<Button title="kacem" descri="this is kacem's profile" src={kacem} >kacem</Button>



  </div>
  );
}

export default App;

I also thought about making a function to hide the other buttons, so I made a simple function to start simply, which is the isShown that makes the button red, but it didn't work. i don't know what's wrong, so if i know where the fault is, i can change it so that it changes the other buttons' display to hidden, using their id. Maybe I can use the state too? in the component, where the onclick props is defined, is it possible to write another line, making the display of the other buttons hidden, with the other one this.setState({display:'block'} still there? is there something that's contrary to this to affect the other elements?

If possible, you could also show me how to make the three buttons in the same line. Thank you!

2 Answers 2

2

working codesandbox

Button.js

import React from "react";
const clicked = {
  width: "50px",
  height: "50px",
  display: "inline-block"
};

export default class Button extends React.Component {
  state = {
    status: false
  };

  clickButton = () => {
    const status = this.props.status;
    this.setState({ status: !status });
    this.props.onChange(this.props.user.id);
  };
  render() {
    return (
      <div style={{ float: "left" }}>
        <button
          onClick={this.clickButton}
          style={this.props.status ? clicked : null}
        >
          {this.props.children}
        </button>
        {this.props.status && (
          <div>
            <h1>{this.props.user.name}</h1>
            <img
              src={this.props.user.imgSrc}
              style={{ width: "30px" }}
              alt=""
            />
            <p>{this.props.user.description}</p>
          </div>
        )}
      </div>
    );
  }
}

App.js

import React from "react";
import Button from "./Button";

const userList = [
  {
    id: 1,
    name: "user1",
    description: "user1 profile",
    imgSrc:
      "https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Brad_Pitt_Fury_2014.jpg/330px-Brad_Pitt_Fury_2014.jpg"
  },
  {
    id: 2,
    name: "user2",
    description: "user2 profile",
    imgSrc:
      "https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Brad_Pitt_Fury_2014.jpg/330px-Brad_Pitt_Fury_2014.jpg"
  },
  {
    id: 3,
    name: "user3",
    description: "user3 profile",
    imgSrc:
      "https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Brad_Pitt_Fury_2014.jpg/330px-Brad_Pitt_Fury_2014.jpg"
  }
];
export default class App extends React.Component {
  state = {
    selectedUserId: null
  };
  handleClick = id => {
    this.setState({ selectedUserId: id });
  };
  render() {
    return userList.map(user => (
      <div key={user.id}>
        <Button
          status={user.id === this.state.selectedUserId ? true : false}
          user={user}
          onChange={this.handleClick}
        >
          {user.name}
        </Button>
      </div>
    ));
  }
}

I had to remove some images and js files in order to run your code. And for aligning them in one line there are several ways, the one I used is to apply float:left to each Button component. Let me know if it was helpful.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your effort! however, one small detail is that, when i click on harold, for instance, I would only like harold to be there, and the others to be hidden. your code, as i tested it after reading, makes me able to click on one button to show and hide its content, but that doesn't affect the rest-what my question is all about!
@AliChbinou sorry! I updated the codesandbox link and also the code blocks in my answer.
2

App.js must have an state that holds the active button, then it can decide which text to be shown, and you have to give each person a unique id in order to specify the selected one.

App.js

...
state = {
  selected: null;
}
...
render() {
  const persons = [
    {
      id: '001',
      name: 'sarah',
      discr: 'some description...'
    },
    {
      ...
    },
    ...
  ]

  return(
    persons.map((p, index) => (<Button {...p} active={this.state.selected === p.id} onClick={() => this.setState({selected: p.id})} />

Button.js

<button onClick={this.props.onClick}>
  {this.props.name}
</button>
{ this.props.selected && <h1>
  {this.props.discr}
</h1>}

4 Comments

could you explain me more the maps part? i do know the function and all, but I couldn't understand the {...p} and the active part : )
instead i writing 3 buttons with different title and discription, i simply wrote an array of objects which each objects holds the values of a button and then map it to the Button component, this way your code becomes much cleaner and reproducable.
and <Comp {...p} /> which p is an object like this {name: 'ali', discr: 'Chbinou'}, is exactly the same as <Comp name='ali' discr='Chibinou' />. It's just another syntax, but much shorter.
and the active part, as you can see everytime you click on a button, the id of that button store in active state, this way we can seperate the active button from the others by checking that which button's id is equal to the active state (which holds the active button's id). we can do this like this <Button active={this.state.active === p.id} /> , if they're equal, active is true, else it's false. then in Button component i use the passed prop active, to determine whether i show the h1 tag or i don't ( { this.props.active && <h1>{this.props.discript</h1>} )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.