ฉันสามารถอัพเดทอุปกรณ์ประกอบฉากใน React.js ได้ไหม?


217

หลังจากเริ่มทำงานกับ React.js ดูเหมือนว่าpropsตั้งใจจะเป็นแบบคงที่ (ส่งผ่านมาจากองค์ประกอบหลัก) ในขณะที่stateการเปลี่ยนแปลงขึ้นอยู่กับเหตุการณ์ อย่างไรก็ตามฉันสังเกตเห็นในเอกสารอ้างอิงถึงcomponentWillReceivePropsซึ่งรวมถึงตัวอย่างนี้โดยเฉพาะ:

componentWillReceiveProps: function(nextProps) {
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}

นี้น่าจะบ่งบอกว่าคุณสมบัติสามารถเปลี่ยนในส่วนขึ้นอยู่กับการเปรียบเทียบของการnextProps this.propsฉันพลาดอะไรไป อุปกรณ์ประกอบฉากเปลี่ยนไปอย่างไรหรือฉันเข้าใจผิดว่าเรื่องนี้ถูกเรียกไปที่ใด?

คำตอบ:


249

ส่วนประกอบไม่สามารถอัปเดตอุปกรณ์ประกอบฉากของตัวเองได้เว้นแต่จะเป็นอาร์เรย์หรือวัตถุ (มีส่วนประกอบที่อัปเดตอุปกรณ์ประกอบฉากของตัวเองแม้ว่าจะเป็นไปได้คือรูปแบบการต่อต้าน) แต่สามารถอัปเดตสถานะและอุปกรณ์ประกอบฉากของลูก ๆ

ตัวอย่างเช่นแดชบอร์ดมีspeedเขตข้อมูลในสถานะของมันและส่งผ่านไปยังมาตรวัดลูกที่แสดงความเร็วนี้ ใช้วิธีการที่เป็นเพียงrender return <Gauge speed={this.state.speed} />เมื่อสายแดชบอร์ดthis.setState({speed: this.state.speed + 1}), speedมาตรวัดเป็นอีกครั้งที่แสดงผลด้วยค่าใหม่สำหรับ

ก่อนหน้านี้สิ่งที่เกิดขึ้นcomponentWillReceivePropsจะมีการเรียกเกจของเกจเพื่อให้เกจมีโอกาสเปรียบเทียบค่าใหม่กับค่าเก่า


ดังนั้นดูเหมือนว่าจะถูกเรียกครั้งเดียวเมื่อองค์ประกอบ React เริ่มต้นและได้รับอุปกรณ์ประกอบฉาก อุปกรณ์ประกอบฉากไม่ได้ "เปลี่ยน" จริง ๆ เมื่อมีการสร้างส่วนประกอบ นั่นถูกต้องใช่ไหม?
Matt Huggins

12
ตรงข้าม. เอกสารกล่าวว่า "เรียกเมื่อเป็นส่วนประกอบที่จะได้รับอุปกรณ์ประกอบฉากใหม่วิธีการนี้ไม่ได้เรียกว่าสำหรับการเริ่มต้นทำให้.."
Valéry

ขอบคุณ คำถามนี้มาจากความเข้าใจผิดเบื้องต้นของ React ซึ่งส่วนประกอบจะถูกนำมาใช้ซ้ำเมื่อทำการเรนเดอร์หน้าจอใหม่อีกครั้ง (หรือบางส่วนของหน้าจอ)
Matt Huggins

1
ใช่. คอมโพเนนต์สามารถฟังเหตุการณ์และอัพเดตสถานะในแต่ละครั้งที่เหตุการณ์เริ่มทำงาน
Valéry

8
ผมมาจากอนาคต: componentWillReceivePropsล้าสมัยขณะนี้: และถูกแทนที่ด้วยการรวมกันของและgetDerivedStateFromProps componentDidUpdate
bvdb

53

PROPS

ส่วนประกอบที่ตอบโต้ควรใช้อุปกรณ์ประกอบฉากเพื่อเก็บข้อมูลที่สามารถเปลี่ยนแปลงได้ แต่สามารถเปลี่ยนแปลงได้โดยส่วนประกอบที่แตกต่างกันเท่านั้น

สถานะ

องค์ประกอบการตอบสนองควรใช้สถานะในการจัดเก็บข้อมูลที่ตัวเองสามารถเปลี่ยนแปลงได้

ตัวอย่างที่ดีมีให้โดยValéryแล้ว


4
@ali_adravi คำพูดเหล่านั้นถูกคัดลอกมาจากที่อื่นไหม? ถ้าเป็นเช่นนั้นการอ้างอิงคืออะไร? หรือว่าคำของคุณและคุณเพียงแค่จัดรูปแบบพวกเขาเป็นคำพูดสำหรับการเน้น?
Rob Bednark

@RobBednark ฉันจำแหล่งที่แน่นอนไม่ได้ในตอนนี้ แต่แน่ใจว่าเป็นข้อความจริงที่มีการปรับเปลี่ยนเล็กน้อยในประโยคจากหนังสือบางเล่ม
Ali Adravi

26

อุปกรณ์ประกอบฉากสามารถเปลี่ยนแปลงได้เมื่อผู้ปกครองขององค์ประกอบทำให้ส่วนประกอบอีกครั้งด้วยคุณสมบัติที่แตกต่างกัน ฉันคิดว่านี่เป็นการเพิ่มประสิทธิภาพเป็นส่วนใหญ่ดังนั้นจึงไม่จำเป็นต้องมีองค์ประกอบใหม่


3

เคล็ดลับเพื่ออัปเดตอุปกรณ์ประกอบฉากหากพวกเขาเป็นอาร์เรย์:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button
} from 'react-native';

class Counter extends Component {
  constructor(props) {
    super(props);
      this.state = {
        count: this.props.count
      }
    }
  increment(){
    console.log("this.props.count");
    console.log(this.props.count);
    let count = this.state.count
    count.push("new element");
    this.setState({ count: count})
  }
  render() {

    return (
      <View style={styles.container}>
        <Text>{ this.state.count.length }</Text>
        <Button
          onPress={this.increment.bind(this)}
          title={ "Increase" }
        />
      </View>
    );
  }
}

Counter.defaultProps = {
 count: []
}

export default Counter
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

3
ฉันคิดว่าการเริ่มต้นสถานะด้วยอุปกรณ์ประกอบฉากเป็นรูปแบบการต่อต้านควรหลีกเลี่ยง นี่คือการเชื่อมโยงที่ดีในการอ่านgithub.com/vasanthk/react-bits/blob/master/anti-patterns/...
tryHendri


0

หากคุณใช้recomposeให้ใช้mapPropsเพื่อสร้างอุปกรณ์ประกอบฉากใหม่ที่ได้รับจากอุปกรณ์ประกอบฉากที่เข้ามา

แก้ไขตัวอย่าง:

import { compose, mapProps } from 'recompose';

const SomeComponent = ({ url, onComplete }) => (
  {url ? (
    <View />
  ) : null}
)

export default compose(
  mapProps(({ url, storeUrl, history, ...props }) => ({
    ...props,
    onClose: () => {
      history.goBack();
    },
    url: url || storeUrl,
  })),
)(SomeComponent);

โปรดระบุตัวอย่าง
vsync
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.