标签: react-redux

如何优化React + Redux中嵌套组件的道具的小更新?

示例代码:https://github.com/d6u/example-redux-update-nested-props/blob/master/one-connect/index.js

观看现场演示:http://d6u.github.io/example-redux-update-nested-props/one-connect.html

如何优化嵌套组件的道具的小更新?

我有上面的组件,Repo和RepoList.我想更新第一个仓库的标签(第14行).所以我发出了一个UPDATE_TAG动作.在我实施之前shouldComponentUpdate,调度大约需要200毫秒,这是预料之中的,因为我们浪费了很多时间<Repo/>来分析没有改变的东西.

添加后shouldComponentUpdate,调度大约需要30ms.在生产构建React.js之后,更新仅花费大约17ms.这要好得多,但Chrome开发者控制台中的时间线视图仍然表示jank帧(超过16.6ms).

在此输入图像描述

想象一下,如果我们有这样的许多更新,或者<Repo/>比当前更新更复杂,我们将无法维持60fps.

我的问题是,对于嵌套组件的道具的这种小更新,是否有更高效和规范的方式来更新内容?我还可以使用Redux吗?

我通过用tags可观察的内部减速器替换每一个来获得解决方案.就像是

// inside reducer when handling UPDATE_TAG action
// repos[0].tags of state is already replaced with a Rx.BehaviorSubject
get('repos[0].tags', state).onNext([{
  id: 213,
  text: 'Node.js'
}]);
Run Code Online (Sandbox Code Playgroud)

然后我使用https://github.com/jayphelps/react-observable-subscribe在Repo组件中订阅它们的值.这很有效.即使使用React.js的开发构建,每个调度仅花费5ms.但我觉得这是Redux中的反模式.

更新1

我按照Dan Abramov的回答中的建议,将我的状态更新的连接组件规范化

新的状态形状是:

{
    repoIds: ['1', '2', '3', ...],
    reposById: {
        '1': {...},
        '2': {...}
    }
}
Run Code Online (Sandbox Code Playgroud)

我加了console.time各地 …

javascript reactjs redux react-redux

43
推荐指数
1
解决办法
1万
查看次数

Redux-Form初始值来自

我正在尝试使用API​​中的数据填充配置文件表单.不幸的是,在这种情况下,redux-form不想与我合作.出于某种原因,无论我做什么,田地都会空着

由于某种原因,设置固定值而不是从reducer传递的值很好.

也许这是因为我在动作创建者中使用redux-promise进行API调用?我怎么能忍受它并摆脱它.这是我的表单组件.

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import { fetchRoleList, fetchUserData } from '../actions';

class UserEdit extends Component {

    componentWillMount() {
        this.props.fetchRoleList();
        this.props.fetchUserData();
    }

    handleEditProfileFormSubmit(formProps) {
        console.log(formProps);
    }

    getRoleOptions(selected_id) {
        if (!this.props.profile) {
            return <option>No data</option>;
        }

        return this.props.profile.roles.map(role => {
            return <option key={role.role_id} value={role.role_id}>{role.name}</option>;
        });
    }

    renderField(props) {
        const { input, placeholder, label, value, type, meta: { touched, error } } …
Run Code Online (Sandbox Code Playgroud)

reactjs redux redux-form react-redux

43
推荐指数
2
解决办法
3万
查看次数

预计在箭头函数结束时返回一个值

一切工作正常,但我有这个警告Expected to return a value at the end of arrow function array-callback-return,我尝试使用forEach,而不是map,但后来<CommentItem />甚至不显示.如何解决?

  return this.props.comments.map((comment) => {
  
      if (comment.hasComments === true) {
      
        return (
          <div key={comment.id}>
          
            <CommentItem className="MainComment"/>

              {this.props.comments.map(commentReply => {
              
                if (commentReply.replyTo === comment.id) { 
                  return (
                    <CommentItem className="SubComment"/>
                 ) // returnt
                } // if-statement
              }) // map-function
              } // map-function __begin
            
          </div> // comment.id
          
        ) // return
Run Code Online (Sandbox Code Playgroud)

javascript ecmascript-6 reactjs redux react-redux

43
推荐指数
5
解决办法
6万
查看次数

“错误:重新渲染太多。React 限制渲染次数以防止无限循环。”

嗨,我一直被困在 React Function 中useState。我只是想学习 hooks 和 useState,但我什至费力寻找解决方案也没有任何进展。这是我的完整反应功能:

import React, { useState } from 'react';
import './MainPart.css';

function MainPart(props) {
  const [orderData_, setOrderData_] = useState(props.orderData);

  let topicData_ = props.topicData;
  let titleData_ = props.titleData;
  let infoData_ = props.infoData;

  return (
    <div className='MainPart'>
      <div className='mainWindow'>{getPics(orderData_)}</div>
      <div className='information'>
        <div className='moreNewsDivs'>
          <div className='moreNewsDiv1'>
            <h4>MORE NEWS</h4>
          </div>
          <div className='moreNewsDiv2'>
            <button
              className='previous-round'
              onClick={setOrderData_(previous(orderData_))}
            >
              &#8249;
            </button>
            &nbsp;&nbsp; &nbsp;&nbsp;
            <button href='/#' className='next-round'>
              &#8250;
            </button>
          </div>
        </div>
        <hr />
        <div className='topicDiv'>
          <h5 className='topicData'>{topicData_}</h5>
          <h5 className='titleData'>{titleData_}</h5>
          <h6 className='infoData'>{infoData_}</h6> …
Run Code Online (Sandbox Code Playgroud)

reactjs react-redux react-hooks

43
推荐指数
3
解决办法
6万
查看次数

“AsyncThunkAction&lt;any, void, {}&gt;”类型的参数不可分配给“AnyAction”类型的参数

商店.ts

export const store = configureStore({
    reducer: {
        auth: authReducer
    },
    middleware: [],
});

export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
Run Code Online (Sandbox Code Playgroud)

钩子.ts

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
Run Code Online (Sandbox Code Playgroud)

authSlice.ts(导致问题的函数)

export const fetchUser = createAsyncThunk(
    'users/fetchByTok',
    async () => {
        const res = await getUser();
        return res.data;
    }
)
Run Code Online (Sandbox Code Playgroud)

授权ts

const Auth = ({ component, isLogged }: {component: any, isLogged: boolean}) => {
    const dispatch = useAppDispatch();
    
    useEffect(() => …
Run Code Online (Sandbox Code Playgroud)

reactjs redux-thunk react-redux redux-toolkit

43
推荐指数
6
解决办法
6万
查看次数

组件在响应同步输入时挂起

错误:组件在响应同步输入时挂起。这将导致 UI 被替换为加载指示器。要修复此问题,应使用 startTransition 包装挂起的更新。

当我从组件 B 导航到 A 时,我想保留组件 A 的先前状态。在 React v17 和 React Router v5 中,我能够实现先前的状态。但是使用 React v18,我收到了上述错误。任何想法?

A组份:

const ComponentA = React.lazy(() => import('./ComponentA'));

const App = () => (
  <Suspense fallback={<Loader/>}>
     <Provider store={store}>
       <ComponentA/>
     </Provider>
  </Suspense>
)
Run Code Online (Sandbox Code Playgroud)

组分B:

const ComponentB = React.lazy(() => import('./ComponentB'));

const App = () => (
  <Suspense fallback={<Loader/>}>
    <Provider store={store}>
      <ComponentB/>
    </Provider>
  </Suspense>
)
Run Code Online (Sandbox Code Playgroud)

节点:v16.14.2 React:v18 React 路由器:v6

Redux v8 不支持 React v18 https://github.com/reduxjs/react-redux/issues/1740

reactjs react-router react-redux

43
推荐指数
1
解决办法
6万
查看次数

访问mapDispatchToProps方法中的State

我使用redux编写了一个容器组件,我对mapDispathToProps的实现看起来像这样

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        onChange: (newValue) => {
            dispatch(updateAttributeSelection('genre', newValue));
            dispatch(getTableData(newValue, ownProps.currentYear));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,为了获取getTableData,我需要一些其他组件的状态.如何在此方法中访问状态对象?

redux react-redux

41
推荐指数
3
解决办法
2万
查看次数

使用HOC与组件包装之间的区别

我刚刚在React中查看了HOC.他们很酷.但是,不是简单地包装组件就能达到相同的效果吗?

高阶分量

这个简单的HOC将状态作为属性传递给ComposedComponent

const HOC = ComposedComponent => class extends React.Component {

    ... lifecycle, state, etc;...

    render() {
      return (<ComposedComponent {...this.state} />);
    }      

}
Run Code Online (Sandbox Code Playgroud)

组件包装

此组件将state作为属性传递给子组件

class ParentComponent extends React.Component {

    ... lifecycle, state, etc;...

    render() {
      return (
        <div>
          {React.cloneElement(this.props.children, { ...this.state })}  
        </div>
      );
    }      

}
Run Code Online (Sandbox Code Playgroud)

尽管两者之间的使用略有不同,但它们似乎都可以重复使用.

通过this.props.children,HOC和组成组件之间的真正区别在哪里?是否有例子只能使用其中一个?使用HOC是一种更好的做法.这些只是您选择自己喜欢的风味的选择吗?

higher-order-functions reactjs react-router react-redux

41
推荐指数
2
解决办法
8396
查看次数

"无状态功能组件不能给出参考"是什么意思?

我有这个:

const ProjectsSummaryLayout = ({projects}) => {
   return (
      <div className="projects-summary col-md-10">
          <h3>Projects</h3>
          <ul>
              { projects.map(p => <li key={p.id}>{p.contract.client}</li>) }
          </ul>
      </div>
   )
}

const ProjectsSummary = connect(
   state => ({projects: state.projects})
)(ProjectsSummaryLayout)
Run Code Online (Sandbox Code Playgroud)

我得到:

警告:无法为无状态函数组件提供refs(请参阅Connect(ProjectsSummaryLayout)创建的ProjectsSummaryLayout中的ref"wrappedInstance").尝试访问此参考将失败.

它试图告诉我什么?我实际上做错了吗?

在这里看到关于这个的讨论,但不幸的是我根本不理解结论.

javascript reactjs redux react-redux

40
推荐指数
1
解决办法
3万
查看次数

如何在redux中设置初始状态

我正在试图弄清楚如何在redux中为商店设置初始状态.我使用https://github.com/reactjs/redux/blob/master/examples/todos-with-undo/reducers/index.js作为示例.我试图修改代码,以便todos初始化了一个值.

const todoApp = combineReducers({
  todos,
  visibilityFilter
}, {
  todos: [{id:123, text:'hello', completed: false}]
})
Run Code Online (Sandbox Code Playgroud)

遵循文档:http://redux.js.org/docs/api/createStore.html

但它不起作用,我不太清楚为什么.

reactjs redux react-redux

40
推荐指数
2
解决办法
6万
查看次数