Reactjs setState () ด้วยชื่อคีย์แบบไดนามิกหรือไม่


248

แก้ไข: นี่คือสิ่งซ้ำซ้อนดูที่นี่

ฉันไม่พบตัวอย่างใด ๆ ของการใช้ชื่อคีย์แบบไดนามิกเมื่อตั้งค่าสถานะ นี่คือสิ่งที่ฉันต้องการจะทำ:

inputChangeHandler : function (event) {
    this.setState( { event.target.id  : event.target.value } );
},

โดยที่ event.target.id ใช้เป็นรหัสสถานะที่จะอัพเดท สิ่งนี้เป็นไปไม่ได้ในการตอบโต้?


4
นี่เป็นคำถามที่ซ้ำกันเกี่ยวกับคีย์วัตถุแบบไดนามิก มันไม่เฉพาะเจาะจงที่จะตอบสนอง
Cory Danielson

9
var newstate = {}; newstate [event.target.id] = event.target.id; this.setState (newstate);
Cory Danielson

ขอบคุณฉันไม่ได้มีความเข้าใจที่ดีเกี่ยวกับการใช้วัตถุโดยทั่วไป
ตราด


@trad ฉันมีปัญหานี้ แต่คุณวางอะไรในสถานะเริ่มต้นของคุณ? มันไม่สำคัญใช่มั้ย
Raphael Onofre

คำตอบ:


280

ขอบคุณคำแนะนำของ @ Cory ฉันใช้สิ่งนี้:

inputChangeHandler : function (event) {
    var stateObject = function() {
      returnObj = {};
      returnObj[this.target.id] = this.target.value;
         return returnObj;
    }.bind(event)();

    this.setState( stateObject );    
},

หากใช้ ES6 หรือBabel transpilerเพื่อแปลงรหัส JSX ของคุณคุณสามารถทำได้ด้วยชื่อคุณสมบัติที่คำนวณได้เช่นกัน:

inputChangeHandler : function (event) {
    this.setState({ [event.target.id]: event.target.value });
    // alternatively using template strings for strings
    // this.setState({ [`key${event.target.id}`]: event.target.value });
}

27
นอกจากนี้ยังมีไวยากรณ์ใหม่สำหรับสิ่งนี้หากคุณใช้ bablejs เพื่อสร้างรหัสของคุณ คุณสามารถใช้computed property names
คอรีแดเนียล

วิธีที่สองทำให้เกิดข้อผิดพลาดทางไวยากรณ์ในเบราว์เซอร์บน WIndows (IE, Chrome) มีใครสังเกตเห็นไหม?
benjaminz

วิธีการรับแจ้ง
Muneem Habib

ขอบคุณtradนี่คือสิ่งที่ฉันกำลังมองหาเพื่อหลีกเลี่ยงการทำสำเนารหัสสำหรับ<Radio />การใช้งาน
Adesh M

6
หากคุณตั้งค่าสถานะโดยใช้ชื่อคุณสมบัติที่คำนวณเช่นนี้this.setState({ [event.target.id]: event.target.value });แล้วคุณจะเข้าถึงสถานะนั้นได้this.state......อย่างไร
user3574492

142

เมื่อคุณต้องการจัดการองค์ประกอบการป้อนข้อมูลที่มีการควบคุมหลายรายการคุณสามารถเพิ่มแอตทริบิวต์ชื่อให้กับแต่ละองค์ประกอบและให้ฟังก์ชันตัวจัดการเลือกสิ่งที่ต้องดำเนินการตามค่าของ event.target.name

ตัวอย่างเช่น:

inputChangeHandler(event) {
  this.setState({ [event.target.name]: event.target.value });
}


7
วงเล็บรอบ [event.target.name] ระบุว่าอะไร ทำไมพวกเขาต้องการ?
798719

1
เมื่อเปรียบเทียบกับวิธีปกติในการตั้งชื่อแต่ละองค์ประกอบแยกเช่น this.setState ({ชื่อผู้ใช้: e.target.value}); สิ่งนี้จะจัดการองค์ประกอบหลาย ๆ แบบของฟอร์มเป็นอาร์เรย์และไม่จำเป็นต้องตั้งค่าแต่ละองค์ประกอบ
vikram jeet singh

1
แต่ยังฉันจะเข้าถึงสถานะนั้นในลักษณะเดียวกันได้อย่างไร ชอบthis.state([event.target.name])ไหม
Kirankumar Dafda

1
ฉันคิดว่าเอกสารเว็บ MDNและโพสต์นี้อธิบายว่าทำไมเราจึงต้องใช้วงเล็บ
Kelli

46

ฉันทำสิ่งนี้สำเร็จ ...

inputChangeHandler: function(event) {
  var key = event.target.id
  var val = event.target.value
  var obj  = {}
  obj[key] = val
  this.setState(obj)
},

ฉันทำวิธีที่คล้ายกัน แต่ปัญหาก็คือมันยังไม่ได้แสดงองค์ประกอบและฉันวิ่งเสาไปโพสต์ (รวมถึงนี้: D) และบางแห่งพบว่า: this.forceUpdate();ซึ่งไม่ควรเป็นกรณีที่มีปฏิกิริยาล่าสุด มาดูกันว่าปัญหาคืออะไรในภายหลัง !!
xploreraj

24

ฉันแค่อยากจะเพิ่มว่าคุณยังสามารถใช้การจัดโครงสร้างเพื่อ refactor รหัสและทำให้ดู neater

inputChangeHandler: function ({ target: { id, value }) {
    this.setState({ [id]: value });
},

10

ในลักษณะวนกับ.mapงานเช่นนี้:

{
    dataForm.map(({ id, placeholder, type }) => {
        return <Input
            value={this.state.type}
            onChangeText={(text) => this.setState({ [type]: text })}
            placeholder={placeholder}
            key={id} />
    })
}

จดบันทึกพารามิเตอร์[]in typeหวังว่าจะช่วย :)


10

ฉันมีปัญหาที่คล้ายกัน

ฉันต้องการตั้งค่าสถานะที่เก็บคีย์ระดับ 2 ไว้ในตัวแปร

เช่น this.setState({permissions[perm.code]: e.target.checked})

อย่างไรก็ตามนี่ไม่ใช่ไวยากรณ์ที่ถูกต้อง

ฉันใช้รหัสต่อไปนี้เพื่อบรรลุสิ่งนี้:

this.setState({
  permissions: {
    ...this.state.permissions,
    [perm.code]: e.target.checked
  }
});


2

ฉันกำลังมองหาวิธีแก้ปัญหาที่สวยและเรียบง่ายและฉันพบสิ่งนี้:

this.setState({ [`image${i}`]: image })

หวังว่านี่จะช่วยได้


1
this.setState({ [`${event.target.id}`]: event.target.value}, () => {
      console.log("State updated: ", JSON.stringify(this.state[event.target.id]));
    });

โปรดทราบตัวละครพูด


0

สถานะของคุณด้วยพจนานุกรมอัปเดตบางคีย์โดยไม่เสียค่าอื่น ๆ

state = 
{   
    name:"mjpatel"  
    parsedFilter:
    {
      page:2,
      perPage:4,
      totalPages: 50,
    }
}

วิธีแก้ไขอยู่ด้านล่าง

 let { parsedFilter } = this.state
 this.setState({
      parsedFilter: {
        ...this.state.parsedFilter,
        page: 5
      }
  });

นี่คือการปรับปรุงค่าสำหรับคีย์ "หน้า" ด้วยค่า 5


-4

สามารถใช้ไวยากรณ์สเปรดได้ดังนี้:

inputChangeHandler : function (event) {
    this.setState( { 
        ...this.state,
        [event.target.id]: event.target.value
    } );
},

7
ปฏิกิริยาจะทำการรวมวัตถุสำหรับคุณนี่คือการปฏิบัติที่ไม่ดี
Rohmer

1
โดยทั่วไปถ้าคุณมีวัตถุภายในและคุณต้องการเปลี่ยนหนึ่งคุณสมบัติในวัตถุภายในที่คุณทำเช่นนี้: this.setState ({selectedItems: {... selectedItems, [item.id]: true}})
Eran หรือ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.