2015-12-18 15 views
5

Tôi đang cố gắng tạo thành phần hộp kiểm tuỳ chỉnh (thực tế là ba trạng thái, nhưng điều đó không liên quan trừ khi nói rằng tôi không chỉ sử dụng INPUT) và tôi không chắc cách tôi có thể thay đổi "kiểm tra" từ các lần nhấp vào chính nó và từ một tập hợp giá trị sắp xuống từ cấp độ gốc.Làm cách nào để quản lý trạng thái trên thành phần React có thể có trạng thái đã thay đổi từ cha mẹ hoặc từ các sự kiện trên đó?

Hiện tại, tôi có nó hoạt động như một thành phần tự cung cấp một prop onChange với trình xử lý gọi lại mà nó gọi để gửi giá trị thành phần cha sau khi nhấp chuột. Nó sử dụng một trạng thái để lưu trữ kiểm tra, được tham chiếu bởi màn hình.

Nếu nó chỉ đơn thuần là một màn hình của kiểm tra, với giá trị được quản lý từ bên ngoài, tôi muốn sử dụng đạo cụ, một cách tự nhiên. Nếu đó chỉ là một thành phần hộp kiểm tự cung cấp giá trị ban đầu thì chỉ trả lời các lần nhấp, tôi sẽ sử dụng trạng thái, như tôi, nhưng vấn đề của tôi là tôi muốn nó có thể nhấp để tự bật và tắt, và cho phép phụ huynh bật và tắt nó.

Tôi là người mới bắt đầu với React và "Cách suy nghĩ phản ứng" vì vậy tôi nghi ngờ tôi đang tiếp cận sai lầm này. Tôi có ấn tượng rằng cách thích hợp để làm điều này là để trở thành thành phần chỉ hiển thị đã chuyển các nhấp chuột lên cha mẹ để xử lý và nhận các bản cập nhật đạo cụ cho các thay đổi giá trị từ cha mẹ, nhưng điều đó sẽ làm cho thành phần không thể tái sử dụng được nhiều hơn, theo ý tôi.

Vậy làm cách nào để tôi thực hiện thay đổi hộp kiểm từ cả nguồn nội bộ lẫn nguồn gốc?

Các liên kết có liên quan cũng được hoan nghênh.

Trả lời

7

Bạn có thể điều trị các hộp kiểm như một phần câm, có nghĩa là nó không giữ bất kỳ trạng thái nội, nhưng chỉ nhận dữ liệu từ bên ngoài thông qua đạo cụ và sau đó render chúng. Bạn có thể xem định nghĩa chi tiết của các thành phần câm here.

Trong khi đó, khi hộp kiểm được nhấp, sự kiện này sẽ được xử lý bởi cha mẹ của thành phần, hoặc tổ tiên sự kiện này được gọi là dữ liệu ngược dòng chảy, được mô tả trong bài viết trên blog của Facebook Thinking in React.

Hơn nữa, để quyết định thành phần nên giữ trạng thái nhất định, tôi tìm thấy những hướng dẫn sau đây rất hữu ích:

Hãy nhớ rằng: Phản ứng là tất cả về một chiều dòng chảy dữ liệu xuống hệ thống phân cấp thành phần. Nó có thể không được ngay lập tức rõ ràng mà thành phần nên sở hữu những gì nhà nước. Đây thường là phần khó khăn nhất đối với người mới hiểu, nên làm theo các bước sau để con số nó ra:

Đối với mỗi mảnh của nhà nước trong ứng dụng của bạn:

  • Xác định tất cả các thành phần mà ám một cái gì đó dựa trên trạng thái đó.
  • Tìm một thành phần chủ sở hữu chung (một thành phần duy nhất phía trên tất cả các thành phần cần trạng thái trong cấu trúc phân cấp).
  • Hoặc chủ sở hữu chung hoặc thành phần khác cao hơn trong cấu trúc phân cấp phải sở hữu trạng thái.
  • Nếu bạn không thể tìm thấy thành phần có ý nghĩa sở hữu tiểu bang, hãy tạo một thành phần mới chỉ đơn giản là giữ trạng thái và thêm nó vào đâu đó trong cấu trúc phân cấp phía trên thành phần chủ sở hữu chung.

Đoạn pseudo-code:

const Checkbox = React.createClass({ 
    // Propagate the event to parents 
    onClick(evt) { 
    if (this.props.handleClick) { 
     this.props.handleClick({checked: evt.target.value}); 
    } 
    }, 

    render() { 
    return (
     this.props.checked ? 
     <Input onClick={this.onClick} type="checkbox" label="Checkbox" checked></Input> : 
     <Input onClick={this.onClick} type="checkbox" label="Checkbox"></Input> 
    ); 
    } 
}); 

const Container = React.createClass({ 
    handleClick(evt) { 
    // Change the container's state, which eventually changes the checkbox's view via props. 
    this.setState({checked: evt.checked}); 
    }, 

    render() { 
    return (
     <div><Checkbox checked={this.state.checked} handleClick={this.handleClick}></Checkbox></div> 
    ); 
    } 
}); 
+0

Đúng, có vẻ như tôi cần làm gì. Tôi bắt đầu di chuyển suy nghĩ của mình từ những ý tưởng "lữ đoàn" cũ của tôi (nơi dữ liệu được xử lý trên cơ sở cần thiết bởi một thành phần riêng lẻ) với nhiều ý tưởng "trung tâm kiểm soát" trung tâm mà React sử dụng. Tôi chỉ không nhận ra rằng triết lý là tất cả-bao gồm, đó là của tôi treo lên. Và cảm ơn cho các liên kết bài viết, quá. – SuperFLEB

3

Bạn chỉ thay đổi từ chỉ cha mẹ.

class ParentComponent extends React.Component{ 
    handleChildCheck(){ 
    this.setState({ 
    childChecked: !this.state.childChecked 
    }) 
    } 
    render(){ 
    return(
     <ChildComponent checked={this.state.childChecked} handleCheck={this.handleChildCheck.bind(this)} /> 
    ) 
} 
} 

Bây giờ nếu bạn muốn kiểm soát tình trạng kiểm tra từ <ChildComponent/> chỉ cần gọi this.props.handleCheck() từ <ChildComponent/>

Bằng cách này các điều khiển sẽ luôn luôn có sẵn trong <ChildComponent/> qua this.props.handleCheck() trong <ParentComponent/> qua this.handleChildCheck().

+0

Được rồi, sau khi nhìn vào đó và noodling xung quanh một chút thêm về riêng tôi, tôi nghĩ rằng tôi nhận được nó. Về cơ bản, thành phần Checkbox (con) chỉ nên đối phó với việc kiểm tra prop, hiển thị chính xác như vậy, và truyền theo bất kỳ sự kiện tương tác (nhấp chuột) nào đến một trình xử lý cha (handleChildCheck, trong ví dụ của bạn). Mọi thứ khác, bao gồm logic của cách nhấp vào hộp kiểm thực sự đặt prop kiểm tra, nên được xử lý trong phụ huynh và rơi xuống cho trẻ thông qua đạo cụ. Điều đó có đúng không? – SuperFLEB

+0

Có, đúng. Điều đó phù hợp với cách suy nghĩ của React! –

-2

Sử dụng truy vấnSelectorTất cả để tìm thành phần của bạn. Thêm trình xử lý sự kiện để theo dõi các thay đổi. Khi thay đổi, hãy chạy truy vấn khácSelectorAll để tìm trẻ em và tắt hoặc bật. Điều này có thể không bao gồm tất cả nhu cầu của bạn nhưng nó sẽ giúp bạn bắt đầu đi đúng hướng. Đây là javascript đơn giản nên không cần thư viện nào khác.

// Finds radios with class on-off and disables 'name-on' elements when 
 
// 'name' is off. 
 

 
function initOfOff() { 
 
    var mains = document.querySelectorAll('.on-off'); 
 

 
    for (var i = 0; i < mains.length; i++) { 
 
    var el = mains[i]; 
 
    var name = el.getAttribute('name'); 
 
    el.addEventListener('click', function() { 
 
     var value = this.getAttribute('value'); 
 
     var children = document.querySelectorAll('.' + name + '-on'); 
 
     for (var i = 0; i < children.length; i++) { 
 
     var child = children[i]; 
 
     child.checked = false; 
 
     if (value == "off") { 
 
      child.setAttribute('disabled', 'disabled'); 
 
     } else { 
 
      child.removeAttribute('disabled'); 
 
     } 
 
     } 
 
    }); 
 
    } 
 
} 
 
initOfOff()
<form name='myform'>power 
 
    <input type='radio' value='on' class='on-off' name='power'>ON | 
 
    <input type='radio' value='off' class='on-off' name='power'>Off 
 
    <dir>lights 
 

 
    <input type='radio' value='on' class='power-on' name='lights'>ON | 
 
    <input type='radio' value='off' class='power-on' name='lights'>OFF 
 
    </dir> 
 
</form>

+0

Xin lỗi, tôi nên đề cập rằng tôi đang tìm giải pháp React cụ thể. (Tôi không thực sự gửi đến SO tất cả những gì nhiều, vì vậy tôi vẫn còn một chút mờ với các chi tiết của phân loại.) Tôi đã thay đổi các thẻ và tiêu đề cho phù hợp. Cảm ơn bạn đã đào sâu vào nó. – SuperFLEB

Các vấn đề liên quan