简体   繁体   中英

React - Render Objects with changing Props

Simply put, I would like to build an interface with which a user can insert objects into a div.

The user should be able to select placed objects and change their settings (color, size, rotation ..).

I am brand new to react and have put my ideas into practice.

class Elements extends React.Component {
constructor(props) {
    super(props);
    this.displayData = [];

    this.state = {
        showdata: this.displayData,
        elementData: {
            color: "red",
        }
    };
    this.addDiv = this.addDiv.bind(this);
    this.switchColor = this.switchColor.bind(this);
    this.giveConsoleData = this.giveConsoleData.bind(this);
};

giveConsoleData(){
    console.log(this.state);
}
switchColor() {
    if(this.state.elementData.color == "red"){
        this.setState({
            showdata: this.displayData,
            elementData: {
                color: "blue",

            }
        });
    }else if(this.state.elementData.color == "blue"){
        this.setState({
            showdata: this.displayData,
            elementData: {
                color: "red",

            }
        });
    }
}
addDiv() {
    this.displayData.push(<div style={this.state.elementData} ><FaArrowUp size={32} /></div>);
    this.setState({
        showdata : this.displayData
    });
}
render() {
    const items = this.state.showdata.map(i => <li>{i}</li>);
    return (
        <div>
            <Button type="submit" block variant="primary" onClick={this.addDiv}>Primary</Button>< br/>
            <Button type="submit" block variant="primary" onClick={this.switchColor}>ChangeColor</Button>< br/>
            <Button type="submit" block variant="primary" onClick={this.giveConsoleData}>Consolenlog</Button>< br/>


            {items}

            <div style={this.state.elementData}><h1>I Can Change</h1></div>

        </div>
    );
}
}

export default Elements;

My problem now is that the h1 heading can change color, but objects that have already been placed cannot.

Do I have the completely wrong approach?

Is it maybe that when you push the div element the current color value is saved and not the color element from the state?

Compiling my comments into an answer with some code:

It think you are right in your suspicion. I would pass this.state.elementData to your component in render() not in addDiv() .

I would also not recommend storing React components in an array. I would store data in the array, and then in your render function, decide what to render based on the data. With your current example, the only thing your displayData needs to keep track of is how many items to render. Then in render you can simply render that many <div style={this.state.elementData} ><FaArrowUp size={32} /></div> s.

Here's how I would change up your code (albeit a little rushed) to attempt what you are describing:

Updated CodePen: https://codepen.io/zekehernandez/pen/RwPLavZ

class Elements extends React.Component {
constructor(props) {
    super(props);

    this.state = {
        showdata: [],
        elementData: {
            color: "red",
        }
    };
    this.addDiv = this.addDiv.bind(this);
    this.switchColor = this.switchColor.bind(this);
    this.giveConsoleData = this.giveConsoleData.bind(this);
};

giveConsoleData(){
    console.log(this.state);
}
switchColor() {
    if(this.state.elementData.color == "red"){
        this.setState({
            elementData: {
                color: "blue",

            }
        });
    }else if(this.state.elementData.color == "blue"){
        this.setState({
            elementData: {
                color: "red",

            }
        });
    }
}
addDiv() {
  this.setState((state, props) => {
    showdata : state.showdata.push(state.showdata.length)
  });
}
render() {

    return (
        <div>
            <button type="submit" block variant="primary" onClick={this.addDiv}>Add Object</button>< br/>
            <button type="submit" block variant="primary" onClick={this.switchColor}>ChangeColor</button>< br/>
            <button type="submit" block variant="primary" onClick={this.giveConsoleData}>Consolenlog</button>< br/>


            {this.state.showdata.map(itemIndex => (
              <div style={this.state.elementData} >item: {itemIndex}</div>
            ))} 

            <div><h1 style={this.state.elementData}>I Can Change</h1></div>

        </div>
    );
  }
}

React.render(<Elements />, document.getElementById('app'));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM