Điều hướng theo chương trình bằng bộ định tuyến phản ứng V4

352
Colin Witkamp 2017-02-09 10:46.

Tôi vừa thay thế react-routertừ v3 sang v4.
Nhưng tôi không chắc làm thế nào để điều hướng theo chương trình trong hàm thành viên của a Component. tức là trong handleClick()chức năng tôi muốn điều hướng đến /path/some/wheresau khi xử lý một số dữ liệu. Tôi đã từng làm điều đó bằng cách:

import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')

Nhưng tôi không thể tìm thấy các giao diện như vậy trong v4.
Làm cách nào để điều hướng bằng v4?

16 answers

424
rgommezz 2017-02-09 11:51.

Nếu bạn đang nhắm mục tiêu môi trường trình duyệt, bạn cần sử dụng react-router-domgói, thay vì react-router. Họ đang theo cách tiếp cận tương tự như React đã làm, để tách lõi, ( react) và mã cụ thể của nền tảng, ( react-dom, react-native) với sự khác biệt nhỏ là bạn không cần cài đặt hai gói riêng biệt, vì vậy các gói môi trường chứa mọi thứ bạn cần. Bạn có thể thêm nó vào dự án của mình dưới dạng:

yarn add react-router-dom

hoặc là

npm i react-router-dom

Điều đầu tiên bạn cần làm là cung cấp một <BrowserRouter>thành phần mẹ hàng đầu nhất trong ứng dụng của bạn. <BrowserRouter>sử dụng historyAPI HTML5 và quản lý nó cho bạn, vì vậy bạn không phải lo lắng về việc tự khởi tạo nó và chuyển nó xuống <BrowserRouter>thành phần như một chỗ dựa (như bạn cần làm trong các phiên bản trước).

Trong V4, để điều hướng theo chương trình, bạn cần phải truy cập vào historyđối tượng, có sẵn thông qua React context, miễn là bạn có thành phần <BrowserRouter> nhà cung cấp là thành phần gốc cao nhất trong ứng dụng của bạn. Thư viện hiển thị thông qua ngữ cảnh routerđối tượng, mà bản thân nó chứa historynhư một thuộc tính. Các historygiao diện cung cấp một số phương pháp định vị, chẳng hạn như push, replacegoBack, trong số những người khác. Bạn có thể kiểm tra toàn bộ danh sách các thuộc tính và phương thức tại đây .

Lưu ý quan trọng cho người dùng Redux / Mobx

Nếu bạn đang sử dụng redux hoặc mobx làm thư viện quản lý trạng thái trong ứng dụng của mình, bạn có thể đã gặp sự cố với các thành phần cần nhận biết vị trí nhưng không được hiển thị lại sau khi kích hoạt cập nhật URL

Điều đó xảy ra bởi vì react-routerchuyển locationđến các thành phần sử dụng mô hình ngữ cảnh.

Cả hai kết nối và trình quan sát tạo ra các thành phần có phương thức shouldComponentUpdate thực hiện so sánh nông giữa các đạo cụ hiện tại và đạo cụ tiếp theo của chúng. Các thành phần đó sẽ chỉ hiển thị lại khi có ít nhất một hỗ trợ đã thay đổi. Điều này có nghĩa là để đảm bảo họ cập nhật khi vị trí thay đổi, họ sẽ cần được cung cấp một chỗ dựa thay đổi khi vị trí thay đổi.

2 cách tiếp cận để giải quyết vấn đề này là:

  • Bao bọc thành phần được kết nối của bạn trong một không đường dẫn <Route />. locationĐối tượng hiện tại là một trong những đạo cụ mà a <Route>chuyển đến thành phần mà nó hiển thị
  • Bọc thành phần được kết nối của bạn với thành phần withRouterbậc cao hơn, trên thực tế, thành phần đó có cùng tác dụng và tiêm locationnhư một giá đỡ

Đặt điều đó sang một bên, có bốn cách để điều hướng theo chương trình, được sắp xếp theo đề xuất:

1.- Sử dụng một <Route>thành phần

Nó thúc đẩy một phong cách khai báo. Trước v4, <Route />các thành phần được đặt ở đầu cấu trúc phân cấp thành phần của bạn, bạn phải nghĩ trước về cấu trúc các tuyến của bạn. Tuy nhiên, bây giờ bạn có thể có <Route>các thành phần ở bất kỳ đâu trong cây của mình, cho phép bạn kiểm soát tốt hơn đối với việc hiển thị có điều kiện tùy thuộc vào URL. RouteTiêm match, locationhistorynhư đạo cụ vào thành phần của bạn. Các phương pháp định vị (ví dụ như push, replace, goBack...) có sẵn như là thuộc tính của historyđối tượng.

Có 3 cách để làm cho một cái gì đó với một Route, bằng cách sử dụng một trong hai component, renderhoặc childrenđạo cụ, nhưng không sử dụng nhiều hơn một trong cùng Route. Lựa chọn phụ thuộc vào trường hợp sử dụng, nhưng về cơ bản hai tùy chọn đầu tiên sẽ chỉ hiển thị thành phần của bạn nếu thành phần pathkhớp với vị trí url, trong khi với childrenthành phần sẽ được hiển thị cho dù đường dẫn có khớp với vị trí hay không (hữu ích cho việc điều chỉnh giao diện người dùng dựa trên URL phù hợp).

Nếu bạn muốn tùy chỉnh đầu ra vẽ thành phần của bạn , bạn cần phải quấn thành phần của bạn trong một chức năng và sử dụng các rendertùy chọn, để vượt qua thành phần của bạn bất kỳ đạo cụ khác mà bạn mong muốn, ngoài match, locationhistory. Một ví dụ để minh họa:

import { BrowserRouter as Router } from 'react-router-dom'

const ButtonToNavigate = ({ title, history }) => (
  <button
    type="button"
    onClick={() => history.push('/my-new-location')}
  >
    {title}
  </button>
);

const SomeComponent = () => (
  <Route path="/" render={(props) => <ButtonToNavigate {...props} title="Navigate elsewhere" />} />
)    

const App = () => (
  <Router>
    <SomeComponent /> // Notice how in v4 we can have any other component interleaved
    <AnotherComponent />
  </Router>
);

2.- Sử dụng withRouterHoC

Thành phần thứ tự cao hơn này sẽ tiêm các đạo cụ giống như Route. Tuy nhiên, nó mang theo hạn chế là bạn chỉ có thể có 1 HoC cho mỗi tệp.

import { withRouter } from 'react-router-dom'

const ButtonToNavigate = ({ history }) => (
  <button
    type="button"
    onClick={() => history.push('/my-new-location')}
  >
    Navigate
  </button>
);


ButtonToNavigate.propTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired,
  }),
};

export default withRouter(ButtonToNavigate);

3.- Sử dụng một Redirectthành phần

Hiển thị một <Redirect>sẽ điều hướng đến một vị trí mới. Nhưng hãy nhớ rằng, theo mặc định , vị trí hiện tại được thay thế bằng vị trí mới, chẳng hạn như chuyển hướng phía máy chủ (HTTP 3xx). Vị trí mới được cung cấp bởi toprop, có thể là một chuỗi (URL để chuyển hướng đến) hoặc một locationđối tượng. Thay vào đó, nếu bạn muốn đẩy một mục mới vào lịch sử , hãy vượt qua một chỗ dựa pushvà đặt nó thànhtrue

<Redirect to="/your-new-location" push />

4.- Truy cập routerthủ công thông qua ngữ cảnh

Một chút không khuyến khích vì ngữ cảnh vẫn là một API thử nghiệm và nó có khả năng bị hỏng / thay đổi trong các bản phát hành React trong tương lai

const ButtonToNavigate = (props, context) => (
  <button
    type="button"
    onClick={() => context.router.history.push('/my-new-location')}
  >
    Navigate to a new location
  </button>
);

ButtonToNavigate.contextTypes = {
  router: React.PropTypes.shape({
    history: React.PropTypes.object.isRequired,
  }),
};

Không cần phải nói cũng có các thành phần Router khác dành cho hệ sinh thái không phải trình duyệt, chẳng hạn như <NativeRouter>sao chép ngăn xếp điều hướng trong bộ nhớ và nhắm mục tiêu nền tảng React Native, có sẵn thông qua react-router-nativegói.

Để tham khảo thêm, đừng ngần ngại xem qua các tài liệu chính thức . Ngoài ra còn có một video được thực hiện bởi một trong những đồng tác giả của thư viện cung cấp phần giới thiệu khá thú vị về react-router v4, nêu bật một số thay đổi lớn.

155
Jikku Jose 2017-05-24 00:30.

Cách dễ nhất để hoàn thành công việc:

this.props.history.push("/new/url")

Ghi chú:

  • Bạn có thể muốn chuyển history proptừ thành phần mẹ xuống thành phần mà bạn muốn gọi hành động nếu nó không khả dụng.
56
Alex Mann 2017-02-19 10:19.

Tôi đã gặp sự cố tương tự khi chuyển sang React-Router v4, vì vậy tôi sẽ cố gắng giải thích giải pháp của mình bên dưới.

Vui lòng không coi câu trả lời này là cách phù hợp để giải quyết vấn đề, tôi tưởng tượng có nhiều khả năng điều gì đó tốt hơn sẽ phát sinh khi React Router v4 trở nên hoàn thiện hơn và rời khỏi bản beta (Nó thậm chí có thể đã tồn tại và tôi chỉ không phát hiện ra) .

Đối với ngữ cảnh, tôi gặp sự cố này vì tôi thỉnh thoảng sử dụng Redux-Sagađể thay đổi đối tượng lịch sử theo chương trình (giả sử khi người dùng xác thực thành công).

Trong tài liệu của Bộ định tuyến React, hãy xem <Router> thành phần và bạn có thể thấy bạn có khả năng chuyển đối tượng lịch sử của riêng mình thông qua một phần mềm hỗ trợ. Đây là bản chất của giải pháp - chúng tôi cung cấp các đối tượng lịch sử để React-Routertừ một thế giới mô-đun.

Các bước:

  1. Cài đặt mô-đun npm lịch sử - yarn add history hoặc npm install history --save
  2. tạo một tệp có tên history.jstrong App.jsthư mục cấp của bạn (đây là tùy chọn của tôi)

    // src/history.js
    
    import createHistory from 'history/createBrowserHistory';
    export default createHistory();`
    
  3. Thêm đối tượng lịch sử này vào thành phần Bộ định tuyến của bạn như vậy

    // src/App.js
    
    import history from '../your/path/to/history.js;'
    <Router history={history}>
    // Route tags here
    </Router>
    
  4. Điều chỉnh URL giống như trước đây bằng cách nhập đối tượng lịch sử chung của bạn :

    import history from '../your/path/to/history.js;'
    history.push('new/path/here/');
    

Mọi thứ sẽ được đồng bộ hóa ngay bây giờ và bạn cũng có quyền truy cập vào cách thiết lập đối tượng lịch sử theo lập trình chứ không phải thông qua thành phần / vùng chứa.

47
Lyubomir 2017-04-11 11:41.

TL; DR:

if (navigate) {
  return <Redirect to="/" push={true} />
}

Câu trả lời đơn giản và mang tính khai báo là bạn cần sử dụng <Redirect to={URL} push={boolean} />kết hợp vớisetState()

push: boolean - khi true, chuyển hướng sẽ đẩy một mục mới vào lịch sử thay vì thay thế mục hiện tại.


import { Redirect } from 'react-router'

class FooBar extends React.Component {
  state = {
    navigate: false
  }

  render() {
    const { navigate } = this.state

    // here is the important part
    if (navigate) {
      return <Redirect to="/" push={true} />
    }
   // ^^^^^^^^^^^^^^^^^^^^^^^

    return (
      <div>
        <button onClick={() => this.setState({ navigate: true })}>
          Home
        </button>
      </div>
    )
  }
}

Ví dụ đầy đủ ở đây . Đọc thêm tại đây .

Tái bút. Ví dụ sử dụng ES7 + Bộ khởi tạo thuộc tính để khởi tạo trạng thái. Nhìn vào đây , nếu bạn quan tâm.

25
TheMisir 2019-10-02 12:25.

Sử dụng useHistoryhook nếu bạn đang sử dụng các thành phần chức năng

Bạn có thể sử dụng useHistoryhook để lấy historyinstance.

import { useHistory } from "react-router-dom";

const MyComponent = () => {
  const history = useHistory();
  
  return (
    <button onClick={() => history.push("/about")}>
      Click me
    </button>
  );
}

Cái useHistorymóc cung cấp cho bạn quyền truy cập vào phiên bản lịch sử mà bạn có thể sử dụng để điều hướng.

Sử dụng thuộc historytính bên trong các thành phần trang

React Router đưa một số thuộc tính historyvào các thành phần của trang.

class HomePage extends React.Component {
  render() {
    const { history } = this.props;

    return (
      <div>
        <button onClick={() => history.push("/projects")}>
          Projects
        </button>
      </div>
    );
  }
}

Bọc các thành phần con withRouterđể chèn các thuộc tính của bộ định tuyến

withRouterwrapper đưa các thuộc tính của bộ định tuyến vào các thành phần. Ví dụ: bạn có thể sử dụng trình bao bọc này để đưa bộ định tuyến vào thành phần nút đăng xuất được đặt bên trong menu người dùng.

import { withRouter } from "react-router";

const LogoutButton = withRouter(({ history }) => {
  return (
    <button onClick={() => history.push("/login")}>
      Logout
    </button>
  );
});

export default LogoutButton;
11
user1445685 2017-05-20 12:35.

Bạn cũng có thể chỉ cần sử dụng các đạo cụ để truy cập đối tượng lịch sử: this.props.history.push('new_url')

9
cdi-meo 2017-09-30 05:11.

Bước 1: Chỉ có một thứ cần nhập ở trên cùng:

import {Route} from 'react-router-dom';

Bước 2: Trong Lộ trình của bạn, hãy vượt qua lịch sử:

<Route
  exact
  path='/posts/add'
  render={({history}) => (
    <PostAdd history={history} />
  )}
/>

Bước 3: lịch sử được chấp nhận như một phần của các đạo cụ trong Thành phần tiếp theo, vì vậy bạn có thể chỉ cần:

this.props.history.push('/');

Điều đó thật dễ dàng và thực sự mạnh mẽ.

7
Kaya Toast 2017-12-21 01:34.

Những công việc này:

import { withRouter } from 'react-router-dom';

const SomeComponent = withRouter(({ history }) => (
    <div onClick={() => history.push('/path/some/where')}>
        some clickable element
    </div>); 
);

export default SomeComponent;
5
mpen 2017-06-15 06:08.

Câu trả lời của tôi tương tự như của Alex . Tôi không rõ tại sao React-Router lại làm điều này phức tạp đến vậy. Tại sao tôi phải bọc thành phần của mình bằng một HoC chỉ để có quyền truy cập vào những gì thực chất là toàn cầu?

Dù sao, nếu bạn nhìn vào cách họ triển khai <BrowserRouter>, đó chỉ là một lớp bọc nhỏ xung quanh lịch sử .

Chúng tôi có thể kéo bit lịch sử đó ra để có thể nhập nó từ bất kỳ đâu. Tuy nhiên, mẹo là nếu bạn đang thực hiện kết xuất phía máy chủ và bạn cố gắng truy cập importmô-đun lịch sử, nó sẽ không hoạt động vì nó sử dụng các API chỉ dành cho trình duyệt. Nhưng điều đó không sao vì chúng tôi thường chỉ chuyển hướng theo một nhấp chuột hoặc một số sự kiện phía máy khách khác. Vì vậy, có thể OK để giả mạo nó:

// history.js
if(__SERVER__) {
    module.exports = {};
} else {
    module.exports = require('history').createBrowserHistory();
}

Với sự trợ giúp của webpack, chúng tôi có thể xác định một số vars để chúng tôi biết mình đang ở trong môi trường nào:

plugins: [
    new DefinePlugin({
        '__SERVER__': 'false',
        '__BROWSER__': 'true', // you really only need one of these, but I like to have both
    }),

Và bây giờ bạn có thể

import history from './history';

Từ bất kỳ đâu. Nó sẽ chỉ trả về một mô-đun trống trên máy chủ.

Nếu bạn không muốn sử dụng các vars ma thuật này, bạn sẽ chỉ cần requirevào đối tượng toàn cục khi nó cần (bên trong trình xử lý sự kiện của bạn). importsẽ không hoạt động vì nó chỉ hoạt động ở cấp cao nhất.

5
Noname 2018-04-23 18:54.

Tôi nghĩ rằng @rgommezz bao gồm hầu hết các trường hợp trừ một trường hợp mà tôi nghĩ nó khá quan trọng.

// history is already a dependency or React Router, but if don't have it then try npm install save-dev history

import createHistory from "history/createBrowserHistory"

// in your function then call add the below 
const history = createHistory();
// Use push, replace, and go to navigate around.
history.push("/home");

Điều này cho phép tôi viết một dịch vụ đơn giản với các hành động / lệnh gọi mà tôi có thể gọi để thực hiện điều hướng từ bất kỳ thành phần nào tôi muốn mà không cần thực hiện nhiều HoC trên các thành phần của mình ...

Không rõ tại sao không ai cung cấp giải pháp này trước đây. Tôi hy vọng nó sẽ hữu ích và nếu bạn thấy bất kỳ vấn đề nào với nó, vui lòng cho tôi biết.

4
jar0m1r 2017-03-02 11:10.

Tôi đã thử nghiệm v4 được vài ngày nay và .. tôi yêu thích nó cho đến nay! Nó chỉ có ý nghĩa sau một thời gian.

Tôi cũng có câu hỏi tương tự và tôi thấy việc xử lý nó như cách sau đây hoạt động tốt nhất (và thậm chí có thể là cách nó được dự định). Nó sử dụng trạng thái, một toán tử bậc ba và <Redirect>.

Trong hàm tạo ()

this.state = {
    redirectTo: null
} 
this.clickhandler = this.clickhandler.bind(this);

Trong kết xuất ()

render(){
    return (
        <div>
        { this.state.redirectTo ?
            <Redirect to={{ pathname: this.state.redirectTo }} /> : 
            (
             <div>
               ..
             <button onClick={ this.clickhandler } />
              ..
             </div>
             )
         }

Trong trình xử lý nhấp chuột ()

 this.setState({ redirectTo: '/path/some/where' });

Hy vọng nó giúp. Cho tôi biết.

4
mwieczorek 2017-09-22 04:52.

Tôi đã phải vật lộn với điều này trong một thời gian - một thứ quá đơn giản nhưng lại rất phức tạp, bởi vì ReactJS chỉ là một cách viết ứng dụng web hoàn toàn khác, nó rất xa lạ với dân gian cũ của chúng ta!

Tôi đã tạo một thành phần riêng biệt để trừu tượng hóa mớ hỗn độn:

// LinkButton.js

import React from "react";
import PropTypes from "prop-types";
import {Route} from 'react-router-dom';

export default class LinkButton extends React.Component {

    render() {
        return (
            <Route render={({history}) => (
                <button {...this.props}
                       onClick={() => {
                           history.push(this.props.to)
                       }}>
                    {this.props.children}
                </button>
            )}/>
        );
    }
}

LinkButton.propTypes = {
    to: PropTypes.string.isRequired
};

Sau đó, thêm nó vào render()phương pháp của bạn :

<LinkButton className="btn btn-primary" to="/location">
    Button Text
</LinkButton>
3
rodrigocfd 2017-09-26 16:10.

Vì không có cách nào khác để đối phó với thiết kế khủng khiếp này, tôi đã viết một thành phần chung sử dụng phương pháp withRouter HOC . Ví dụ bên dưới đang bao bọc một buttonphần tử, nhưng bạn có thể thay đổi thành bất kỳ phần tử có thể nhấp nào mà bạn cần:

import React from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';

const NavButton = (props) => (
  <Button onClick={() => props.history.push(props.to)}>
    {props.children}
  </Button>
);

NavButton.propTypes = {
  history: PropTypes.shape({
    push: PropTypes.func.isRequired
  }),
  to: PropTypes.string.isRequired
};

export default withRouter(NavButton);

Sử dụng:

<NavButton to="/somewhere">Click me</NavButton>
3
Shashwat Gupta 2019-12-30 01:39.
this.props.history.push("/url")

Nếu bạn không tìm thấy this.props.history có sẵn trong thành phần của mình, thì hãy thử cái này

import {withRouter} from 'react-router-dom'
export default withRouter(MyComponent)  
2
piotr_cz 2017-06-14 08:47.

Đôi khi tôi thích chuyển đổi các tuyến đường bằng Ứng dụng sau đó bằng các nút, đây là một ví dụ làm việc tối thiểu phù hợp với tôi:

import { Component } from 'react'
import { BrowserRouter as Router, Link } from 'react-router-dom'

class App extends Component {
  constructor(props) {
    super(props)

    /** @type BrowserRouter */
    this.router = undefined
  }

  async handleSignFormSubmit() {
    await magic()
    this.router.history.push('/')
  }

  render() {
    return (
      <Router ref={ el => this.router = el }>
        <Link to="/signin">Sign in</Link>
        <Route path="/signin" exact={true} render={() => (
          <SignPage onFormSubmit={ this.handleSignFormSubmit } />
        )} />
      </Router>
    )
  }
}
0
li x 2019-01-12 10:11.

Đối với những người bạn yêu cầu chuyển hướng trước khi kích hoạt hoàn toàn bộ định tuyến bằng cách sử dụng React Routerhoặc React Router DomBạn có thể cung cấp chuyển hướng bằng cách chỉ cần thêm đối tượng lịch sử và đẩy một trạng thái mới lên nó trong cấu trúc của bạn app.js. Hãy xem xét những điều sau:

function getSubdomain(hostname) {
    let regexParse = new RegExp('[a-z\-0-9]{2,63}\.[a-z\.]{2,5}$');
    let urlParts = regexParse.exec(hostname);
    return hostname.replace(urlParts[0], '').slice(0, -1);
}

class App extends Component {

    constructor(props) {
        super(props);


        this.state = {
            hostState: true
        };

        if (getSubdomain(window.location.hostname).length > 0) {
            this.state.hostState = false;
            window.history.pushState('', '', './login');
        } else {
            console.log(getSubdomain(window.location.hostname));
        }

    }


    render() {
        return (

            <BrowserRouter>
                {this.state.hostState ? (
                    <div>
                        <Route path="/login" component={LoginContainer}/>
                        <Route path="/" component={PublicContainer}/>
                    </div>
                ) : (
                    <div>
                        <Route path="/login" component={LoginContainer}/>
                    </div>
                )

                }
            </BrowserRouter>)
    }


}

Ở đây, chúng tôi muốn thay đổi các Định tuyến đầu ra phụ thuộc vào một miền phụ, bằng cách tương tác với đối tượng lịch sử trước khi thành phần hiển thị, chúng tôi có thể chuyển hướng hiệu quả trong khi vẫn giữ nguyên các tuyến của chúng tôi.

window.history.pushState('', '', './login');

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.

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Thời gian, sự kiên nhẫn, thời gian, sự cống hiến và thời gian chỉ là một vài trong số những thứ mà Peter Bellerby cần để thành lập và sau đó điều hành Bellerby & Co. Globemakers, một trong những công ty duy nhất trên Trái đất vẫn sản xuất các quả địa cầu bằng tay.

Năm giai đoạn đau buồn sau khi mất việc làm

Năm giai đoạn đau buồn sau khi mất việc làm

Đó là một ngày thứ Bảy, máy bay của tôi hạ cánh, và tôi đã sẵn sàng để thư giãn trong một kỳ nghỉ cuối tuần ngắn ngủi, khi một email đến trên điện thoại của tôi. Tôi đã mất việc.

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Nếu bạn đã từng bị đánh cắp danh tính của mình, bạn biết đó là một trải nghiệm đáng sợ và căng thẳng. Một cách không phổ biến để ngăn chặn nó? Tín dụng bị đóng băng.

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Eleanor (Kristen Bell) dường như đã tình nguyện cho chúng tôi làm vật tưởng nhớ. NBC's The Good Place là một chương trình thích thử thách tốt.

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