Component vs Pure.Component
Như bạn biết trong lifecycle của React có một function tên là shouldComponentUpdate()
dùng để kiểm tra xem có tiến hành re-render lại component đó không. Với Component
thông thường thì mặc định function này sẽ luôn trả về true đồng nghĩa với việc component của bạn sẽ được re-render lại kể cả khi không có sự thay đổi về state hay props của nó. Để rõ hơn bạn có thể xem ví dụ sau:
class App extends React.Component {
state = {
firstComponentName: "DefaultComponent",
secondComponentName: "PureComponent",
counter: 0
};
handleIncrement = () => {
this.setState(prevState => ({
counter: prevState.counter + 1
}));
};
render() {
return (
<div className="App">
<p>You click: {this.state.counter} time</p>
<DefaultComponent componentName={this.state.firstComponentName} />
<PureComponent componentName={this.state.secondComponentName} />
<button onClick={this.handleIncrement}>Increment</button>
</div>
);
}
}
class DefaultComponent extends React.Component {
componentDidUpdate() {
console.log("Re-render DefaultComponent");
}
render() {
return <h1>{this.props.componentName}</h1>;
}
}
class PureComponent extends React.PureComponent {
componentDidUpdate() {
console.log("Re-render PureComponent");
}
render() {
return <h1>{this.props.componentName}</h1>;
}
}
Như bạn thấy ở đây mình có 1 component cha là <App />
và 2 component con là <DefaultComponent />
và <PureComponent />
. 2 component con này lần lượt sẽ là React.Component
và React.PureComponent
và nhận vào props và componentName
từ component <App />
. Trong mỗi component mình đã thêm hàm componentDidUpdate()
và console.log ra nếu component đó bị re-render. Ngoài ra thì component <App />
còn có một state là counter
và một nút cho phép tăng giá trị này lên. Mỗi khi ta bấm nút đó thì sẽ những thứ sẽ xảy ra như sau:
state.counter
bị thay đổi - cộng thêm một vào giá trị ban đầu- Việc thay đổi state này sẽ dẫn đến component
<App />
bị render lại - Dẫn đến
<DefaultComponent />
cũng bị render lại doReact.Component
thìshouldComponentUpdate()
luôn trả về true. <PureComponent />
không bị render lại (bạn có thể check phần console.log() để biết phần nào bị render lại- Hết =))
Sở dĩ component PureComponent
không bị re-render là do hàm shouldComponentUpdate()
của nó không mặc định trả về true mà ở đây nó tự động thực hiện cái gọi là shallow compare. Cụ thể nó sẽ so sánh dạng như sau:
shouldComponentUpdate(nextProps, nextState) {
return this.props.componentName !== nextProps.componentName
}
- Do ở đây prop ta truyền vào là
componentName
không hề bị thay đổi nên hàm này sẽ trả về false và component này sẽ không bị re-render này. Link demo: https://codesandbox.io/s/component-vs-purecomponent-fqv1x
Render data từ mongodb trong redux
Hàm render của bạn sẽ được chạy trước khi componentDidMount()
chạy cho nên lúc này hàm render sẽ không hiểu cityList
của bạn là gì và báo lỗi lên. Cách xử lý là bạn có thể thêm biến vào redux store ví dụ nhự fetchCityListSuccess = false
. Sau này khi action gọi đến API của bạn thực hiện xong thì bạn đồng thời cập nhật lại fetchCityListSuccess = true
và bên giao diện cũng lấy biến này ra để check xem có nên hiển thị dữ liệu không. Cụ thể bên UI bạn sẽ sửa lại như này:
import React, {Component} from 'react';
import { connect } from 'react-redux';
import {bindActionCreators} from 'redux';
import {getCity} from '../actions/cityRead';
class DisplayCities extends React.Component {
componentDidMount() {
this.props.getCity()
}
cityLine() {
//console.log('city', this.props)
let listImage = this.props.cityList.map((i) =>{
return <img src={i.image} />;
});
return listImage;
}
render() {
return (
<div style={{marginTop: 10}}>
{this.props.fetchCityListSuccess && this.cityLine()}
</div>
);
}
}
const mapStateToProps = (state) => {
return {
cityList: state.cities,
fetchCityListSuccess: state.fetchCityListSuccess,
}
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({getCity: getCity}, dispatch)
}
export default connect(mapStateToProps,mapDispatchToProps)(DisplayCities)
Gitlab bị permission denied mỗi khi mở terminal mới hoặc reboot máy
Bạn có thể tạo thêm 1 file đặt tên là config
và để trong folder .ssh/
với nội dung như sau:
Host gitlab.com
HostName gitlab.com
User username (username của bạn)
IdentityFile ~/.ssh/id_rsa (đường dẫn đến private key của bạn)
Như vậy sau này khi bạn thao tác với gitlab thì nó sẽ tự biết tìm đến key tương ứng của bạn
hỏi html,css
có nhé bạn, bạn có thể tham khảo ví dụ này https://pajasevi.github.io/CSSnowflakes/
ReactJs với Webpack, Babel 7
bạn chụp cho mình phần import file index.css
được không
[ReactJS] Call API trong ComponentDidMount()
bạn nên chia thành 2 component ra chứ không nên gộp chung, 1 component là ProductDetail
và component
RelatedProduct`. Như thế bạn có thể gọi độc lập 2 phần API tùy theo url
Lỗi test file TS sử dụng Jest
bạn thử xóa cái program đi xem
Load lại trang không bị mất dữ liệu
bạn có thể lưu dữ liệu sau mỡi lần chỉnh bấm next hoặc prev vào localStorage
. Sau khi form đã hoàn thành ở step 3 thì xóa trong đó đi. Trong hàm componentDidMount()
thì có thể check xem nếu localStorage
có dữ liệu thì tiến hành khôi phục lại nó.
Fixed Footer trong CSS
bạn có thể thử thay đổi phần position của footer từ fixed thành như sau:
position: sticky;
Lỗi stylelint khi chạy npm start
Hình như bạn đang thiếu file config cho stylelint thì phải. Bạn check lại xem trong project của bạn đã có file định nghĩ rule để chạy stylelint chưa
[ANT - Design ] Làm sao để đặt thời gian tự động chạy cho slide
bạn có thể thêm props autoplaySpeed
và để chỉnh speed chạy như sau:
<Carousel autoplay autoplaySpeed={1000}>
<div><h3>1</h3></div>
<div><h3>2</h3></div>
<div><h3>3</h3></div>
<div><h3>4</h3></div>
</Carousel>
Với 1000 = 1s
Lỗi update ajax laravel
Theo mình nhớ là bạn không gửi được lên trực tiếp bằng phương thức PUT nhé. Trong trường hợp Route của bạn khai báo là PUT, PATCH, hoặc DELETE thì thực tế ở bên client sẽ vẫn gửi là POST kèm với một filed có tên là: _method: 'PUT'
. Bạn có thể xem lại ở đây https://laravel.com/docs/5.7/routing#form-method-spoofing. Với trường hợp của bạn có thể thử thêm như sau:
data.append('_method', 'PUT');
ReactJS - Parameterized Event Handlers
Bạn có thể hiểu cơ bản như sau với cách cách dùng arrow function
thứ nhất:
handleClick(param, e) {
console.log('Parameter', param);
console.log('Event', e);
}
render() {
<button onClick={(e) => this.handleClick(param, e)}></button>
}
thì mỗi lần hàm render()
được gọi thì nó sẽ phải tạo lại cái instance của hàm handleClick
rồi gán vào cái sự kiện onClick
mà bạn khai báo. Còn với cách dùng thứ 2:
handleClick = (e) => {
console.log('Event', e);
}
render() {
<button onClick={this.handleClick}></button>
}
sẽ tránh được việc tạo lại mỗi lần hàm render()
được phải tạo lại cái instance nói trên kia mà nó sẽ dùng lại cái instance tạo ra lần đầu render
Cải thiện chức năng trên viblo - Gửi nhóm phát triển Viblo
Bạn để ý ở trong khung của trình soạn thảo bên phải icon cái mắt có cái hình mũi tên 4 hướng, bạn click và đó sẽ phóng t phần soạn thỏa và ẩn phần title cũng như tag đi đó
Lưu nhiều dữ liệu vào state có ảnh hưởng đến hiệu năng của ứng dụng không
Mình chưa làm project nào có lượng data lưu trong store quá lớn tuy nhiên như bạn nói là muốn cache lại data từ server thì có lẽ sẽ phù hợp hơn nếu bạn lưu vào LocalStorage hoặc sử dụng một số loại database cho js như https://pouchdb.com/
Tạo images layout giống như Unsplash
layout của Unsplash là dạng masory-layout, bạn thử dùng thư viện này xem https://masonry.desandro.com/
Xây dựng database kiến thức cho mình để sau này search lại.
Hiện tại mình đang dùng 1 app tên là Pocket để lưu những đường link kiến thức mình thấy hay. App này hỗ trợ bạn đặt tag cho các link theo chủ đề mong muồn và sau này có thể lọc được theo tag đồng thời cũng hỗ trợ tìm kiếm theo tiêu đề hoặc url mà bạn đã lưu lại. Đồng thời cũng có cả phiên bản cho web. Bạn có thể dùng thử ở đây https://getpocket.com
Tại sao khi click lần đầu tiên hành động chưa thực thi ngay
Theo code hiện tại của bạn thì sau khi bạn click lần đầu tiên thì nó mới tiến hành gán sự kiện này vào thẻ div
itemAccor.onclick = () => itemAccor.classList.toggle("active");
Nếu bạn muốn nó chạy ngay lần đâu tiên thì nên khai báo phần gán function này ở trong hàm componentDidMount()
luôn như này:
class Accordion extends React.Component {
componentDidMount() {
const myAccor = this.getEle.children;
console.log(myAccor);
for (let i = 0; i < myAccor.length; i++) {
console.log(myAccor[i]);
let itemAccor = myAccor[i];
itemAccor.onclick = () => itemAccor.classList.toggle("active");
}
}
render() {
return (
<div
ref={ele => this.getEle = ele}
onClick={this.handleClick}>
{this.props.children}
</div>
)
}
}
class App extends React.Component {
render() {
return (
<Accordion>
<div className="accor">
<div className="head">Head 1</div>
<div className="body">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
<div className="accor">
<div className="head">Head 2</div>
<div className="body">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</Accordion>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
url() và route()
Giả sử bạn dùng cùng hàm url() cho nhiều hơn 1 form và khi có yêu cầu cần sửa đổi url trong đó web.php thì bạn sẽ mất công tìm đến tất cả các nơi dùng để sửa đổi. Hoặc đơn giản bạn dùng 1 hàm url() thì cũng sẽ cần tìm đến đúng file để cập nhật. Còn khi dùng hàm route() thì bạn chỉ cần sửa ở đúng file web.php và tất cả vị trí sử dụng url ứng với route() đó sẽ được cập nhật