Program source code

Github.com/astak16/act…

The project structure

src/common; // Public components
src/pages; / / page
src/static; // Static resources
src/store; / / the main store
App.js; / / the root component
index.css; / / style
index.js; // Import file
Copy the code

Reset CSS

Search reset.css and copy it over

styled-components

Once a CSS file is introduced in a file, it takes effect globally

Writing CSS this way is a bit of a problem, as there is a risk that styles will be overwritten when there are multiple components on the page

We want to write styles that are independent of each other

use

  1. Rename index.css to style.js

  2. Introduce style.js in index.js

    import "style.js";
    Copy the code
  3. style.js

    import { injectGlobal } from "styled-components";
    
    injectGlobal` body{ padding: 10px } `;
    Copy the code

Used in components

Component declarations

// Header/style.js
import styled from "styled-components";

export const HeaderWrapper = styled.div` height: 56px; `;

// Header/index.js
import { HeaderWrapper } from "./style";

class Header extends Component {
  render() {
    return <HeaderWrapper></HeaderWrapper>; }}Copy the code

Images using

Using background images in style.js will not work if you use background: URL (‘/images/logo.png’), because webpack doesn’t know what the project directory looks like when it’s packaged, it treats the path as a string

I need to write it like this

import logoPic from "/images/logo.png";

export const Logo = style.a`
  background: url(${logoPic})
`;
Copy the code

Set properties

import logoPic from "/images/logo.png";

export const Logo = style.a.attr({
  href: "/",})`
  background: url(${logoPic})
`;
Copy the code

Parameter passing

Styled Provides function functions in which different parameters are passed in the components

<RecommendItem key='1' imgURL='/images/1.png'>1</RecommendItem>
<RecommendItem key='2' imgURL='/images/2.png'>1</RecommendItem>

// style.js
export const RecommendItem = styled.div`
  width: 280px;
  height: 50px;
  background: url(${props => props.imgURL});
  background-size: contain;
`
Copy the code

immutable.js

In reducer, the data of state is not expected to be changed. When the project is written, it is easy to change the state unknowingly, resulting in abnormalities.

Immutable. Js helps by generating an immutable object.

Immutable provides a fromJS method for converting JS objects into IMmutable objects

const a = fromJS({ age: 18 });
Copy the code

Immutable provides two methods to read data: get and getIn

const a = fromJS({
  age: 18
  feature: {
    height: 180}})const age = a.get('age')

const height = a.getIn(['feature'.'height'])
/ / or
const height = a.get('feature').get('height')
Copy the code

Immutable provides the set and merge methods to set data.

The set method of an immutable object returns a completely new object by combining the set value with the value of the previous IMmutable object. It does not modify immutable data.

const a = fromJS({
  age: 18.name: "uccs"}); a.set("age".19).set("name"."tiantain");
/ / or
a.merge({
  age: 1.name: "tiantian"});Copy the code

When an external IMMUTABLE Object is used, the internal Object is also immutable. Therefore, when setting a set, you must first make an ordinary Object immutable.

const a = fromJS({
  list: [].// This list is also immutable
});

const data = [1.2.3];
a.set("list", fromJS(data));
Copy the code

Immutable. Js provides toJS methods to convert immutable objects into JS objects

const a = fromJS({
  list: [1.2.3]});const b = a.toJS();
b[1];
Copy the code

redux-thunk

Redux-thunk allows you to write functions in actions

redux

Redux and React-Redux need to be installed on the first page

React-redux is a convenient way to use redux in React

The use of Redux can be seen here: Redux Study Notes

store/index.js

// store/index.js
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import reducer from "./reducer";

const store = createStore(reducer, compose(applyMiddleware(thunk))); // Use redux-thunk in store

export default store;
Copy the code

store/reducer.js

/ / the main store/reducer. Js
import { combineReducers } from "redux-immutable";
import { headerReducer } from ".. /common/header/store";

export default combineReducers({
  header: headerReducer,
});

/ / points header/store/reducer. Js
import { Search_Focus } from "./actionType";
import { fromJS } from "immutable";
const defaultState = fromJS({
  focused: false.// Default data
});
export default (state = defaultState, action) => {
  switch (action.type) {
    case Search_Focus:
      return state.set("focused", action.data);
    default:
      returnstate; }};Copy the code

Redux-immutable provides a combineReducers method that is used to combine separate reducer files.

header/store/actionCreators.js

// header/store/actionCreators.js
import {Search_Focus} from './actionType'

const searchFocus = (data) = > {
  type: Search_Focus,
  data
}

export const getList = async() = > {return (dispatch) = > {
    const res = await axios.get('api/header.json')
    dispatch(searchFocus(res.data))
  }
}
Copy the code

header/store/actionType.js

// header/store/actionType.js
export const Search_Focus = "header/search_focus";
Copy the code

App.js

// App.js
import { Provider } from "react-redux";
import store from "./store";

<Provider store={store}>
  <BrowserRouter>
    <div>
      <Header />
    </div>
  </BrowserRouter>
</Provider>;
Copy the code

React-redux has a core component Provider that has a store property. We pass the store property to it so that all the components in the Provider can use the store data

Component connection store

The Provider provides stores to components, but components that want to use the data in the Store need to make connections

import { connect } from "react-redux";

class Header extends React.Component {}

export default connect()(Header);
Copy the code

React-redux provides the Connect method, which helps a component connect to a store. Connect accepts two parameters: mapStateToProps and mapDispatchToProps

import { actionCreators } from "./store/actionCreators";

const mapStateToProps = (state) = > {
  return {
    focused: state.getIn(["header"."focused"]),}; };const mapDispatchToProps = (dispatch) = > {
  return{ handleInputFocus() { dispatch(actionCreators.getList()); }}; };export default connect(mapStateToProps, mapDispatchToProps)(Header);
Copy the code

The component uses this.props. Focused

react-router-dom

Route

  • renderMethod can render a thing
  • exactPerfectly matched path
    • exactforfalseWhen,/and/detailThey all match up
  • componentRendering component
import { BrowserRouter, Route } from "react-router-dom";
import Home from "./pages/home";
import Detail from "./pages/detail/loadable";

function App() {
  return (
    <Provider store={store}>
      <BrowserRouter>
        <div>
          <Route path="/" exact component={Home} />
          <Route path="/detail/:id" exact component={Detail} />
        </div>
      </BrowserRouter>
    </Provider>
  );
}

export default App;
Copy the code

animation

There is an icon next to it, and every time you click it, the icon needs to rotate.

Just change the value of the icon’s trannForm: Rotate () every time you click. Each time I increase by 360 degrees

The real nodes rendered by React can be obtained by ref.

<SearchInfoSwitch onClick={() => handleChangePage(this.spinIcon)}> <i className='iconfont spin' ref={icon => this.spinIcon = icon} >&#xe852; A batch of < < / I > change/SearchInfoSwitch > handleChangePage (spin) {let originAngle = spin. The style.css. The transform. The replace (/ [^ 0-9] / ig, '') if (originAngle) originAngle = parseInt(originAngle, 10) else originAngle = 0 spin.style.transform = `rotate(${originAngle + 360}deg)` }Copy the code

other

  1. Use Link instead of A to jump, you can load on demand

  2. PureComponent is equivalent to Component+shouldComponentUpdate

  3. DangerouslySetInnerHTML ={{__html: ‘

    text

    ‘}} Can render HTML content

  4. < the Route path = ‘/ detail / : id / > routing parameters to obtain this. Props. Match. Params. Id

  5. Asynchronous components are redux-immutable. To use asynchronous components, withRouter, export default Connect (mapState, mapDispatch)(withRouter(Detail)) is required.

    // detail/loadable.js
    import React from "react";
    import Loadable from "react-loadable";
    
    const LoadableComponent = Loadable({
      loader: (a)= > import(". /"),
      loading() {
        return <div>Being loaded</div>; }});export default() = ><LoadableComponent />;
    
    // App.js
    import Detail from "./pages/detail/loadable";
    Copy the code

conclusion

routing

Project Technology Stack:

  • react-router: routing
  • react-redux: Data hang your tool
  • react-loadable: Load as required
  • react-transition-groupAnimation:
  • redux-immutableWill:statebecomeimmutableobject
  • redux-thunk: can be inactionUse functions in
  • styled-components: Local style
  • axios:ajaxrequest