Hiểu về React-Redux và mapStateToProps ()

232
Pablo Barría Urenda 2016-07-06 01:42.

Tôi đang cố gắng hiểu phương thức kết nối của react-redux và các chức năng mà nó nhận làm tham số. Đặc biệt mapStateToProps().

Theo cách hiểu của tôi, giá trị trả về của mapStateToPropssẽ là một đối tượng có nguồn gốc từ trạng thái (khi nó nằm trong cửa hàng), có các khóa sẽ được chuyển cho thành phần đích của bạn (áp dụng kết nối thành phần) làm đạo cụ.

Điều này có nghĩa là trạng thái được thành phần đích của bạn sử dụng có thể có cấu trúc hoàn toàn khác với trạng thái được lưu trữ trên cửa hàng của bạn.

Q: Điều này có ổn không?
Q: Điều này có được mong đợi không?
Q: Đây có phải là một mô hình chống?

9 answers

61
Richard Strickland 2017-09-27 04:37.

Q: Is this ok?
A: vâng

Q: Is this expected?
Có, điều này được mong đợi (nếu bạn đang sử dụng react-redux).

Q: Is this an anti-pattern?
A: Không, đây không phải là kiểu chống đối.

Nó được gọi là "kết nối" thành phần của bạn hoặc "làm cho nó thông minh". Đó là do thiết kế.

Nó cho phép bạn tách thành phần khỏi trạng thái của bạn thêm một thời gian nữa, điều này làm tăng tính mô-đun của mã của bạn. Nó cũng cho phép bạn đơn giản hóa trạng thái thành phần của mình như một tập hợp con của trạng thái ứng dụng của bạn, trên thực tế, giúp bạn tuân thủ theo mẫu Redux.

Hãy suy nghĩ về nó theo cách này: một cửa hàng phải chứa toàn bộ trạng thái ứng dụng của bạn.
Đối với các ứng dụng lớn, điều này có thể chứa hàng chục thuộc tính được lồng vào nhiều lớp sâu.
Bạn không muốn vận chuyển tất cả những thứ đó xung quanh mỗi cuộc gọi (tốn kém).

Nếu không có mapStateToPropshoặc một số tương tự của nó, bạn sẽ bị cám dỗ để khắc phục trạng thái của mình theo cách khác để cải thiện hiệu suất / đơn giản hóa.

121
webdeb 2016-07-06 03:46.

Vâng, đúng rồi. Nó chỉ là một chức năng trợ giúp để có một cách đơn giản hơn để truy cập các thuộc tính trạng thái của bạn

Hãy tưởng tượng bạn có một postschìa khóa trong Ứng dụng của mìnhstate.posts

state.posts //
/*    
{
  currentPostId: "",
  isFetching: false,
  allPosts: {}
}
*/

Và thành phần Posts

Theo mặc định, connect()(Posts)tất cả các đạo cụ trạng thái có sẵn cho Thành phần được kết nối

const Posts = ({posts}) => (
  <div>
    {/* access posts.isFetching, access posts.allPosts */}
  </div> 
)

Bây giờ khi bạn ánh xạ state.poststhành phần của mình, nó sẽ đẹp hơn một chút

const Posts = ({isFetching, allPosts}) => (
  <div>
    {/* access isFetching, allPosts directly */}
  </div> 
)

connect(
  state => state.posts
)(Posts)

mapDispatchToProps

bình thường bạn phải viết dispatch(anActionCreator())

với bindActionCreatorsbạn có thể làm điều đó cũng dễ dàng hơn như

connect(
  state => state.posts,
  dispatch => bindActionCreators({fetchPosts, deletePost}, dispatch)
)(Posts)

Bây giờ bạn có thể sử dụng nó trong Thành phần của mình

const Posts = ({isFetching, allPosts, fetchPosts, deletePost }) => (
  <div>
    <button onClick={() => fetchPosts()} />Fetch posts</button>
    {/* access isFetching, allPosts directly */}
  </div> 
)

Cập nhật về actionCreators ..

Ví dụ về actionCreator: deletePost

const deletePostAction = (id) => ({
  action: 'DELETE_POST',
  payload: { id },
})

Vì vậy, bindActionCreatorssẽ chỉ thực hiện các hành động của bạn, gói chúng vào dispatchcuộc gọi. (Tôi đã không đọc mã nguồn của redux, nhưng việc triển khai có thể trông giống như sau:

const bindActionCreators = (actions, dispatch) => {
  return Object.keys(actions).reduce(actionsMap, actionNameInProps => {
    actionsMap[actionNameInProps] = (...args) => dispatch(actions[actionNameInProps].call(null, ...args))
    return actionsMap;
  }, {})
}
40
Mohamed Mellouki 2016-07-06 02:40.

Bạn đã hiểu đúng phần đầu tiên:

Yes mapStateToPropscó trạng thái Store làm đối số / tham số (được cung cấp bởi react-redux::connect) và nó được sử dụng để liên kết thành phần với một phần nhất định của trạng thái store.

Bằng cách liên kết, tôi có nghĩa là đối tượng được trả về mapStateToPropssẽ được cung cấp tại thời điểm xây dựng dưới dạng đạo cụ và mọi thay đổi tiếp theo sẽ có sẵn thông qua componentWillReceiveProps.

Nếu bạn biết mẫu thiết kế Observer thì chính xác là như vậy hoặc một biến thể nhỏ của nó.

Một ví dụ sẽ giúp mọi thứ rõ ràng hơn:

import React, {
    Component,
} from 'react-native';

class ItemsContainer extends Component {
    constructor(props) {
        super(props);

        this.state = {
            items: props.items, //provided by [email protected]
            filteredItems: this.filterItems(props.items, props.filters),
        };
    }

    componentWillReceiveProps(nextProps) {
        this.setState({
            filteredItems: this.filterItems(this.state.items, nextProps.filters),
        });
    }

    filterItems = (items, filters) => { /* return filtered list */ }

    render() {
        return (
            <View>
                // display the filtered items
            </View>
        );
    }
}

module.exports = connect(
    //mapStateToProps,
    (state) => ({
        items: state.App.Items.List,
        filters: state.App.Items.Filters,
        //the State.App & state.App.Items.List/Filters are reducers used as an example.
    })
    // mapDispatchToProps,  that's another subject
)(ItemsContainer);

Có thể có một thành phần phản ứng khác được gọi là itemsFiltersxử lý hiển thị và duy trì trạng thái bộ lọc ở trạng thái Redux Store, thành phần Demo là "lắng nghe" hoặc "đăng ký" với bộ lọc trạng thái Redux Store để bất cứ khi nào bộ lọc lưu trữ thay đổi trạng thái (với sự trợ giúp của filtersComponent) phản ứng -redux phát hiện ra rằng có sự thay đổi và thông báo hoặc "xuất bản" tất cả các thành phần đang nghe / đã đăng ký bằng cách gửi các thay đổi đến chúng componentWillReceivePropsmà trong ví dụ này sẽ kích hoạt bộ lọc các mục và làm mới màn hình do trạng thái phản ứng đã thay đổi .

Hãy cho tôi biết nếu ví dụ gây nhầm lẫn hoặc không đủ rõ ràng để cung cấp giải thích tốt hơn.

Đối với: Điều này có nghĩa là trạng thái được tiêu thụ bởi thành phần mục tiêu của bạn có thể có cấu trúc hoàn toàn khác với trạng thái được lưu trữ trên cửa hàng của bạn.

Tôi không hiểu câu hỏi, nhưng chỉ biết rằng trạng thái react ( this.setState) hoàn toàn khác với trạng thái Redux Store!

Trạng thái phản ứng được sử dụng để xử lý bản vẽ lại và hành vi của thành phần phản ứng. Trạng thái phản ứng được chứa riêng cho thành phần.

Trạng thái Redux Store là sự kết hợp của các trạng thái giảm thiểu Redux, mỗi trạng thái chịu trách nhiệm quản lý một phần logic ứng dụng nhỏ. Các thuộc tính giảm tốc đó có thể được truy cập với sự trợ giúp của react-redux::[email protected]bất kỳ thành phần nào! Điều này làm cho ứng dụng có thể truy cập ở trạng thái cửa hàng Redux trong khi trạng thái thành phần là độc quyền của chính nó.

5
Patrick W. McMahon 2017-09-16 09:07.

Đây phản ứng & Redux dụ được dựa trên ví dụ Mohamed Mellouki của. Nhưng xác nhận sử dụng tô điểmlinting quy tắc . Lưu ý rằng chúng tôi xác định các phương thức điều phối và đạo cụ của mình bằng PropTypes để trình biên dịch của chúng tôi không hét vào mặt chúng tôi. Ví dụ này cũng bao gồm một số dòng mã bị thiếu trong ví dụ của Mohamed. Để sử dụng kết nối, bạn sẽ cần nhập nó từ react-redux . Ví dụ này cũng liên kết method filterItems, điều này sẽ ngăn chặn các vấn đề về phạm vi trong thành phần . Mã nguồn này đã được tự động định dạng bằng JavaScript Prettify .

import React, { Component } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

class ItemsContainer extends Component {
  constructor(props) {
    super(props);
    const { items, filters } = props;
    this.state = {
      items,
      filteredItems: filterItems(items, filters),
    };
    this.filterItems = this.filterItems.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const { itmes } = this.state;
    const { filters } = nextProps;
    this.setState({ filteredItems: filterItems(items, filters) });
  }

  filterItems = (items, filters) => {
    /* return filtered list */
  };

  render() {
    return <View>/*display the filtered items */</View>;
  }
}

/*
define dispatch methods in propTypes so that they are validated.
*/
ItemsContainer.propTypes = {
  items: PropTypes.array.isRequired,
  filters: PropTypes.array.isRequired,
  onMyAction: PropTypes.func.isRequired,
};

/*
map state to props
*/
const mapStateToProps = state => ({
  items: state.App.Items.List,
  filters: state.App.Items.Filters,
});

/*
connect dispatch to props so that you can call the methods from the active props scope.
The defined method `onMyAction` can be called in the scope of the componets props.
*/
const mapDispatchToProps = dispatch => ({
  onMyAction: value => {
    dispatch(() => console.log(`${value}`));
  },
});

/* clean way of setting up the connect. */
export default connect(mapStateToProps, mapDispatchToProps)(ItemsContainer);

Mã ví dụ này là một mẫu tốt để bắt đầu cho thành phần của bạn.

2
ArunValaven 2017-08-03 20:26.

React-Redux connect được sử dụng để cập nhật cửa hàng cho mọi hành động.

import { connect } from 'react-redux';

const AppContainer = connect(  
  mapStateToProps,
  mapDispatchToProps
)(App);

export default AppContainer;

Nó rất đơn giản và rõ ràng được giải thích trong blog này .

Bạn có thể sao chép dự án github hoặc sao chép, dán mã từ blog đó để hiểu kết nối Redux.

1
zloctb 2019-01-12 02:33.

Đây là một phác thảo / bảng soạn sẵn để mô tả hành vi của mapStateToProps:

(Đây là cách triển khai được đơn giản hóa rất nhiều về những gì mà vùng chứa Redux thực hiện.)

class MyComponentContainer extends Component {
  mapStateToProps(state) {
    // this function is specific to this particular container
    return state.foo.bar;
  }

  render() {
    // This is how you get the current state from Redux,
    // and would be identical, no mater what mapStateToProps does
    const { state } = this.context.store.getState();

    const props = this.mapStateToProps(state);

    return <MyComponent {...this.props} {...props} />;
  }
}

và tiếp theo

function buildReduxContainer(ChildComponentClass, mapStateToProps) {
  return class Container extends Component {
    render() {
      const { state } = this.context.store.getState();

      const props = mapStateToProps(state);

      return <ChildComponentClass {...this.props} {...props} />;
    }
  }
}
1
coder9833idls 2020-09-09 00:14.

Đó là một khái niệm đơn giản. Redux tạo một đối tượng trạng thái phổ biến (một cửa hàng) từ các hành động trong bộ giảm. Giống như một thành phần React, trạng thái này không cần phải được mã hóa rõ ràng ở bất kỳ đâu, nhưng nó giúp các nhà phát triển nhìn thấy một đối tượng trạng thái mặc định trong tệp giảm thiểu để hình dung những gì đang xảy ra. Bạn nhập bộ giảm trong thành phần để truy cập tệp. Sau đó mapStateToProps chỉ chọn các cặp khóa / giá trị trong cửa hàng mà thành phần của nó cần. Hãy nghĩ về nó giống như Redux tạo ra một phiên bản toàn cầu của một thành phần React

this.state = ({ 
cats = [], 
dogs = []
})

Không thể thay đổi cấu trúc của trạng thái bằng cách sử dụng mapStateToProps (). Những gì bạn đang làm là chỉ chọn các cặp khóa / giá trị của cửa hàng mà thành phần cần và chuyển các giá trị (từ danh sách khóa / giá trị trong cửa hàng) đến các đạo cụ (khóa cục bộ) trong thành phần của bạn. Bạn làm điều này một giá trị tại một thời điểm trong một danh sách. Không có thay đổi cấu trúc nào có thể xảy ra trong quá trình.

PS Cửa hàng là trạng thái địa phương. Giảm bớt cũng thường chuyển trạng thái cùng với cơ sở dữ liệu với Người tạo hành động tham gia vào hỗn hợp, nhưng hãy hiểu khái niệm đơn giản này trước cho bài đăng cụ thể này.

PPS Cách thực hành tốt là tách các bộ giảm tốc thành các tệp riêng biệt cho mỗi tệp và chỉ nhập bộ giảm tốc mà thành phần cần.

0
Ravi Veliyat 2020-09-01 03:28.

Tôi muốn cấu trúc lại tuyên bố mà bạn đã đề cập, đó là:

Điều này có nghĩa là trạng thái được tiêu thụ bởi thành phần mục tiêu của bạn có thể có cấu trúc hoàn toàn khác với trạng thái được lưu trữ trên cửa hàng của bạn

Bạn có thể nói rằng trạng thái được thành phần đích của bạn sử dụng có một phần nhỏ trạng thái được lưu trữ trên cửa hàng redux. Nói cách khác, trạng thái được sử dụng bởi thành phần của bạn sẽ là tập hợp con của trạng thái của cửa hàng redux.

Theo như sự hiểu biết về phương thức connect (), nó khá đơn giản! Phương thức connect () có khả năng thêm các đạo cụ mới vào thành phần của bạn và thậm chí ghi đè các đạo cụ hiện có. Thông qua phương thức kết nối này, chúng tôi có thể truy cập trạng thái của cửa hàng redux cũng được Nhà cung cấp cung cấp cho chúng tôi. Một sự kết hợp có lợi cho bạn và bạn có thể thêm trạng thái của cửa hàng redux vào các đạo cụ của thành phần của bạn.

Trên đây là một số lý thuyết và tôi khuyên bạn nên xem video này một lần để hiểu rõ hơn về cú pháp.

0
Mohan Krishna Sai 2020-09-24 20:35.

Có, bạn có thể làm điều này. Bạn cũng có thể xử lý trạng thái và trả về đối tượng.

function mapStateToProps(state){  
  let completed = someFunction (state);
   return {
     completed : completed,  
   }
}
 

Điều này sẽ hữu ích nếu bạn muốn chuyển logic liên quan đến trạng thái từ chức năng kết xuất ra bên ngoài nó.

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Một thương hiệu kế thừa khác có được cuộc sống mới khi những người chủ mới của Black Opal có được Hội chợ thời trang

Desiree Rogers, trái, và Cheryl Mayberry McKissack Chuyển sang, Fenty Beauty và Pat McGrath, có một đế chế làm đẹp mới do phụ nữ làm chủ đang trỗi dậy. Sau thương vụ mua lại mỹ phẩm Black Opal vào tháng 9, đội ngũ quyền lực của Giám đốc điều hành công ty Desiree Rogers và Chủ tịch Cheryl Mayberry McKissack đã thông báo mua lại thương hiệu làm đẹp tiên phong Fashion Fair từ người sáng lập Johnson Publishing Company (JPC).

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Ngoài việc trở nên vô nghĩa, các bên bộc lộ giới tính giờ đây đã trở nên chết người

Đối với những người có quá nhiều thời gian, tiệc tiết lộ giới tính là một cách thú vị để không cần áp đặt những định kiến ​​hạn chế lên thai nhi trước một đối tượng bạn bè giả vờ quan tâm một cách lịch sự. Tuy nhiên, việc chỉ dựa vào những chiếc bánh nướng có màu nhân tạo để biểu thị một tiếng hoo-ha hoặc một đứa trẻ đi tè đã trở nên xa xỉ trong các bậc cha mẹ trên Instagram.

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Kirstjen Nielsen đang cố gắng đổi mới bản thân với tư cách là một người phụ nữ 'nói ra sự thật cho sức mạnh'

Hôm thứ Tư, cựu Bộ trưởng An ninh Nội địa Kirstjen Nielsen vì một lý do nào đó đã được đưa ra một diễn đàn để phát biểu tại Hội nghị thượng đỉnh Những người phụ nữ quyền lực nhất của Fortune. Và có thể đoán trước được, người phụ nữ giám sát các nỗ lực (đang diễn ra) của chính quyền Trump nhằm chia cắt các gia đình ở biên giới đã sử dụng thời gian của mình như một cơ hội để tự bảo vệ mình và tự nhận mình là người — và hãy hít thở sâu ở đây — “đã nói sự thật với quyền lực.

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Toyota Racing Development sẽ cho ra mắt Supra 3000GT Concept, Massive Wing vào tháng tới

Vì thế hệ mới nhất của chiếc xe điều chỉnh được yêu thích trên thế giới hiện đã có mặt tại đây, nên chỉ có điều kiện là Toyota Racing Development sẽ đưa phiên bản Supra thế hệ thứ năm sửa đổi của riêng mình đến SEMA vào tháng tới. Toyota đã cho chúng tôi một gợi ý về những gì sẽ xảy ra trong tuần này: một chiếc Concept GR Supra 3000GT hiện đại.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language