Ahora entiendo todo

Tuve que hacer bastante para poder entender como funciona esta cosa,
creo

Resulta que no tengo que joder con las querystrings todo el tiempo, solo
cuando cargo la pagina, de ahi en adelante puedo manejar todo con el
estado y puedo hacer history.pushstate para mostrarle a los usuarios un
link al que pueden acceder y estaran en la misma pagina

por todo esto, ahora ya leo solo la query string al princio y
internamente me manejo con el estado que me da searchbar y navigate, uno
me da una query y el otro me da un page number

de aqui en adelante deberia ir mas facil la cosa

PD: ojala my super mega setup de continuous delivery pueda con mis
modificaciones
This commit is contained in:
Daniel Cortes
2020-06-03 19:49:30 -04:00
parent a525299f44
commit a3f2f5eacf
7 changed files with 136 additions and 75 deletions

129
package-lock.json generated
View File

@@ -1356,17 +1356,6 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
}, },
"@reach/router": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.3.tgz",
"integrity": "sha512-gOIAiFhWdiVGSVjukKeNKkCRBLmnORoTPyBihI/jLunICPgxdP30DroAvPQuf1eVfQbfGJQDJkwhJXsNPMnVWw==",
"requires": {
"create-react-context": "0.3.0",
"invariant": "^2.2.3",
"prop-types": "^15.6.1",
"react-lifecycles-compat": "^3.0.4"
}
},
"@sheerun/mutationobserver-shim": { "@sheerun/mutationobserver-shim": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz", "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz",
@@ -3959,15 +3948,6 @@
"sha.js": "^2.4.8" "sha.js": "^2.4.8"
} }
}, },
"create-react-context": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz",
"integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==",
"requires": {
"gud": "^1.0.0",
"warning": "^4.0.3"
}
},
"cross-spawn": { "cross-spawn": {
"version": "6.0.5", "version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -6212,11 +6192,6 @@
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE="
}, },
"gud": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
},
"gzip-size": { "gzip-size": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
@@ -6355,6 +6330,19 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
}, },
"history": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
"requires": {
"@babel/runtime": "^7.1.2",
"loose-envify": "^1.2.0",
"resolve-pathname": "^3.0.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0",
"value-equal": "^1.0.1"
}
},
"hmac-drbg": { "hmac-drbg": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -6365,6 +6353,14 @@
"minimalistic-crypto-utils": "^1.0.1" "minimalistic-crypto-utils": "^1.0.1"
} }
}, },
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
}
},
"hosted-git-info": { "hosted-git-info": {
"version": "2.8.8", "version": "2.8.8",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
@@ -8282,6 +8278,15 @@
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
}, },
"mini-create-react-context": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz",
"integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==",
"requires": {
"@babel/runtime": "^7.5.5",
"tiny-warning": "^1.0.3"
}
},
"mini-css-extract-plugin": { "mini-css-extract-plugin": {
"version": "0.9.0", "version": "0.9.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
@@ -10837,6 +10842,52 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
}, },
"react-router": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
"requires": {
"@babel/runtime": "^7.1.2",
"history": "^4.9.0",
"hoist-non-react-statics": "^3.1.0",
"loose-envify": "^1.3.1",
"mini-create-react-context": "^0.4.0",
"path-to-regexp": "^1.7.0",
"prop-types": "^15.6.2",
"react-is": "^16.6.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"path-to-regexp": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
"requires": {
"isarray": "0.0.1"
}
}
}
},
"react-router-dom": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
"requires": {
"@babel/runtime": "^7.1.2",
"history": "^4.9.0",
"loose-envify": "^1.3.1",
"prop-types": "^15.6.2",
"react-router": "5.2.0",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0"
}
},
"react-scripts": { "react-scripts": {
"version": "3.4.1", "version": "3.4.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
@@ -11248,6 +11299,11 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
}, },
"resolve-pathname": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
},
"resolve-url": { "resolve-url": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -12720,6 +12776,16 @@
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
}, },
"tiny-invariant": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
"integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
},
"tiny-warning": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
"tmp": { "tmp": {
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -13101,6 +13167,11 @@
"spdx-expression-parse": "^3.0.0" "spdx-expression-parse": "^3.0.0"
} }
}, },
"value-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
},
"vary": { "vary": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -13157,14 +13228,6 @@
"makeerror": "1.0.x" "makeerror": "1.0.x"
} }
}, },
"warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"requires": {
"loose-envify": "^1.0.0"
}
},
"watchpack": { "watchpack": {
"version": "1.7.2", "version": "1.7.2",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz",

View File

@@ -3,7 +3,6 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@reach/router": "^1.3.3",
"@testing-library/jest-dom": "^4.2.4", "@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0", "@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1", "@testing-library/user-event": "^7.2.1",
@@ -17,6 +16,7 @@
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-icons": "^3.10.0", "react-icons": "^3.10.0",
"react-json-view": "^1.19.1", "react-json-view": "^1.19.1",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1", "react-scripts": "3.4.1",
"typescript": "^3.7.5" "typescript": "^3.7.5"
}, },

View File

@@ -1,14 +1,14 @@
import React from "react"; import React from "react";
import {Link} from "@reach/router"; import {Link} from "react-router-dom";
export class Nav extends React.Component { export class Nav extends React.Component {
render() { render() {
return ( return (
<nav className='nav'> <nav className='nav'>
<Link to={'/'}><h1>MusicList</h1></Link> <Link to='/'><h1>MusicList</h1></Link>
<ul className='nav-links'> <ul className='nav-links'>
<li className='link'><a href='/login'>Iniciar Sesion</a></li> <li className='link'><Link to='/login'>Iniciar Sesion</Link></li>
<li className='link'><a href='/signup'>Registrate</a></li> <li className='link'><Link to='/signup'>Registrate</Link></li>
</ul> </ul>
</nav> </nav>
) )

View File

@@ -43,7 +43,7 @@ export default class Paginate extends Component {
gotoPage(page) { gotoPage(page) {
const {onPageChanged = f => f} = this.props; const {onPageChanged = f => f} = this.props;
const currentPage = Math.max(0, Math.min(page, this.totalPages)); const currentPage = Math.max(0, Math.min(page, this.totalPages));
this.setState({currentPage: currentPage}, () => onPageChanged(this.makePageLink(currentPage))); this.setState({currentPage: currentPage}, () => onPageChanged(page));
} }
handleClick(page) { handleClick(page) {

View File

@@ -5,7 +5,7 @@ import ReactJson from "react-json-view";
import {searchArtist} from "../services/search_service"; import {searchArtist} from "../services/search_service";
import SearchBar from "./SearchBar"; import SearchBar from "./SearchBar";
import Paginate from "./Paginate"; import Paginate from "./Paginate";
import {Link, navigate} from "@reach/router"; import {Link} from "react-router-dom";
class SearchArtist extends React.Component { class SearchArtist extends React.Component {
render() { render() {
@@ -34,35 +34,41 @@ export class Search extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.loadParams = this.loadParams.bind(this);
this.makeLink = this.makeLink.bind(this); this.makeLink = this.makeLink.bind(this);
this.handlePageChange = this.handlePageChange.bind(this); this.handlePageChange = this.handlePageChange.bind(this);
this.handleQueryChange = this.handleQueryChange.bind(this); this.handleQueryChange = this.handleQueryChange.bind(this);
const parsed = queryString.parse(this.props.location.search);
this.state = { this.state = {
artists: null, artists: null,
paginate: null, paginate: null,
params: this.loadParams() query: parsed.query,
page: !isNaN(+parsed.page) ? +parsed.page : 1,
}; };
} }
componentDidMount() { componentDidMount() {
this.loadArtists(this.state.params.query, this.state.params.page); this.loadArtists(this.state.query, this.state.page);
}
componentDidUpdate(prevProps, prevState, snapshot) {
if(prevState.query !== this.state.query || prevState.page !== this.state.page){
this.loadArtists(this.state.query, this.state.page);
}
} }
makeLink(page) { makeLink(page) {
return `/search?query=${this.state.params.query}&page=${page}` return `/search?query=${this.state.query}&page=${page}`
} }
async handlePageChange(page) { handlePageChange(page) {
await navigate(page) this.props.history.push(this.makeLink(page));
this.setState({params: this.loadParams()}, () => { this.setState({page: page});
this.loadArtists(this.state.params.query, this.state.params.page);
});
} }
handleQueryChange(query) { handleQueryChange(query) {
this.setState({artists: null, paginate: null, params: this.loadParams()}) this.setState({query: query, page: 1});
} }
render() { render() {
@@ -74,9 +80,8 @@ export class Search extends React.Component {
const currentPage = this.state.paginate.current_page; const currentPage = this.state.paginate.current_page;
const pageLimit = this.state.paginate.per_page; const pageLimit = this.state.paginate.per_page;
paginate = <Paginate totalRecords={total} pageLimit={pageLimit} currentPage={currentPage} paginate = <Paginate totalRecords={total} pageLimit={pageLimit} currentPage={currentPage} pageNeighbours={2}
pageNeighbours={2} onPageChanged={this.handlePageChange} onPageChanged={this.handlePageChange} makeLink={this.makeLink}/>
makeLink={this.makeLink}/>
} }
if (this.state.artists) { if (this.state.artists) {
@@ -91,21 +96,13 @@ export class Search extends React.Component {
return ( return (
<main> <main>
<h1>Busqueda</h1> <h1>Busqueda</h1>
<SearchBar query={this.state.params.query} onQueryChanged={this.handleQueryChange}/> <SearchBar query={this.state.query} onQueryChanged={this.handleQueryChange} history={this.props.history}/>
{paginate && paginate} {paginate && paginate}
{artists ? artists : <p>Loading...</p>} {artists ? artists : <p>Loading...</p>}
</main> </main>
); );
} }
loadParams() {
const parsed = queryString.parse(this.props.location.search);
return {
query: parsed.query,
page: parsed.page
}
}
loadArtists(query, page) { loadArtists(query, page) {
if (!page) { if (!page) {
page = 1; page = 1;

View File

@@ -1,6 +1,5 @@
import React from "react"; import React from "react";
import {FaSearch} from 'react-icons/fa'; import {FaSearch} from 'react-icons/fa';
import {navigate} from "@reach/router";
export default class SearchBar extends React.Component { export default class SearchBar extends React.Component {
constructor(props) { constructor(props) {
@@ -23,9 +22,8 @@ export default class SearchBar extends React.Component {
const query = this.state.query; const query = this.state.query;
const onQueryChanged = this.props.onQueryChanged; const onQueryChanged = this.props.onQueryChanged;
navigate(`/search?query=${query}`).then(() => { this.props.history.push(`/search?query=${query}`)
if(onQueryChanged) onQueryChanged(query) if(onQueryChanged) onQueryChanged(query)
});
} }
} }

View File

@@ -1,17 +1,18 @@
import React, {Fragment} from 'react'; import React, {Fragment} from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import {Search} from './components/Search'; import {Search} from './components/Search';
import {Router} from "@reach/router";
import SearchBar from "./components/SearchBar"; import SearchBar from "./components/SearchBar";
import './styles/reset.css'; import './styles/reset.css';
import './styles/main.css'; import './styles/main.css';
import {Nav} from "./components/Nav"; import {Nav} from "./components/Nav";
const Main = () => ( import {BrowserRouter, Switch, Route} from "react-router-dom";
const Main = (props) => (
<Fragment> <Fragment>
<h1>Busca la musica que te gusta!</h1> <h1>Busca la musica que te gusta!</h1>
<SearchBar/> <SearchBar history={props.history}/>
</Fragment> </Fragment>
) )
@@ -23,12 +24,14 @@ const NoRoute = () => (
const App = () => ( const App = () => (
<main> <main>
<Nav/> <BrowserRouter>
<Router> <Nav/>
<Main path='/'/> <Switch>
<Search path='/search'/> <Route path='/search' component={Search}/>
<NoRoute default/> <Route exact path='/' component={Main}/>
</Router> <Route path='*' component={NoRoute}/>
</Switch>
</BrowserRouter>
</main> </main>
); );