'@' (ที่สัญลักษณ์) ใน Redux @connect decorator คืออะไร


226

ฉันกำลังเรียนรู้ Redux ด้วย React และสะดุดกับรหัสนี้ ฉันไม่แน่ใจว่าเป็นเฉพาะReduxหรือไม่ แต่ฉันได้เห็นข้อมูลโค้ดต่อไปนี้ในหนึ่งในตัวอย่าง

@connect((state) => {
  return {
    key: state.a.b
  };
})

ในขณะที่การทำงานของconnectตรงไปตรงสวย แต่ฉันไม่เข้าใจก่อน@ connectมันไม่ได้เป็นโอเปอเรเตอร์ JavaScript หากฉันไม่ผิด

บางคนสามารถอธิบายได้ว่าอะไรคือสิ่งนี้และทำไมจึงใช้

ปรับปรุง:

อันที่จริงแล้วมันเป็นส่วนหนึ่งreact-reduxที่ใช้เชื่อมต่อส่วนประกอบ React เข้ากับ Redux store


6
ฉันไม่คุ้นเคยกับ Redux แต่ดูเหมือนมัณฑนากร medium.com/google-developers/...
ลี

4
ฉันชอบที่โลกจาวาสคริปต์ใหม่นี้คุณกำลังจ้องมองโค้ดครึ่งเวลาและคิดว่า "ส่วนนี้ของไวยากรณ์ภาษาคืออะไร"
MK

4
ฮ่า ๆ ๆ ตอนนี้ฉันเข้าสู่ Redux แล้ว แต่ก่อนหน้านั้นฉันไม่รู้ว่าไวยากรณ์ของมัณฑนากรไม่มีส่วนเกี่ยวข้องกับการเปลี่ยนถ่าย มันเป็นเพียงแค่จาวาสคริปต์ ดีใจที่ได้เห็นคำถามนี้กำลังช่วยเหลือผู้คนจำนวนมากเช่นฉัน :)
Salman

1
เห็นได้ชัดว่าทีมงาน redux ไม่สนับสนุนการใช้งานการเชื่อมต่อเป็นมัณฑนากรในขณะนี้github.com/happypoulp/redux-tutorial/issues/87
Syed Jafri

คำตอบ:


376

@สัญลักษณ์ในความเป็นจริงการแสดงออก JavaScript เสนอในปัจจุบันที่มีความหมายตกแต่ง :

ผู้ตกแต่งสามารถทำให้คำอธิบายประกอบและปรับเปลี่ยนคลาสและคุณสมบัติได้ในขณะออกแบบ

นี่คือตัวอย่างของการตั้งค่า Redux แบบไม่มีและมี decorator:

ไม่มีมัณฑนากร

import React from 'react';
import * as actionCreators from './actionCreators';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

function mapStateToProps(state) {
  return { todos: state.todos };
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) };
}

class MyApp extends React.Component {
  // ...define your main app here
}

export default connect(mapStateToProps, mapDispatchToProps)(MyApp);

ใช้มัณฑนากร

import React from 'react';
import * as actionCreators from './actionCreators';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

function mapStateToProps(state) {
  return { todos: state.todos };
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) };
}

@connect(mapStateToProps, mapDispatchToProps)
export default class MyApp extends React.Component {
  // ...define your main app here
}

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


46
นี่มันสุดยอดมาก
svnm

2
หนึ่งสามารถยิ่งสั้นกับไวยากรณ์ ES6 @connect (state => {return {todos: state.todos};}, Dispatch => {return {actions: bindActionCreators (actionCreators, Dispatch)};})
LessQuesar

11
หากคุณต้องการที่จะกระชับคุณสามารถใช้ผลตอบแทนโดยนัยใน ES6 ขึ้นอยู่กับว่าคุณต้องการเป็นคนอย่างไร @connect(state => ({todos: state.todos}), dispatch => ({actions: bindActionCreators(actionCreators, dispatch)}))
แทนเนอร์เซมาราด

3
คุณจะส่งออกส่วนประกอบที่ไม่ได้เชื่อมต่อสำหรับการทดสอบหน่วยได้อย่างไร
ทิม

การใช้มัณฑนากรสำหรับ redux พร้อมการตอบสนองการนำทางอาจเป็นปัญหาแนวทางปฏิบัติที่ดีที่สุดในปัจจุบันคือการใช้ฟังก์ชั่นที่ไม่ใช่มัณฑนากร: github.com/react-community/react-navigation/issues/1180
straya

50

สำคัญมาก!

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

ตัวอย่าง: สมมติว่าในองค์ประกอบของคุณคุณต้องการเพียงสองอุปกรณ์ประกอบฉาก:

  1. ข้อความสุดท้าย
  2. ชื่อผู้ใช้

อย่าทำอย่างนี้

@connect(state => ({ 
   user: state.user,
   messages: state.messages
}))

ทำเช่นนี้

@connect(state => ({ 
   user_name: state.user.name,
   last_message: state.messages[state.messages.length-1]
}))

9
หรือใช้ตัวเลือกเช่น reselect หรือ fastmemoize
Julius Koronci

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