如何处理道具更新太慢?

时间:2019-10-14 17:53:03

标签: javascript reactjs redux react-redux react-hooks

编写一个React Hooks组件,该组件呈现Redux中随机选择的引号。

我正在努力在第一个渲染器中读取props的引用(必须在JSX中编写switch语句以从第一个渲染器中的本地React组件状态读取)。

当单击按钮以获取新的随机报价时(即在第一次渲染后很长时间),可以从道具中读取所有内容。猜道具太慢了,无法更新。

最欢迎如何处理它的指针。我所做的更多是黑客行为,因为我第一次渲染时根本没有从Redux商店中读取内容。

const defaultState = {};

const NEW_QUOTE = "NEW_QUOTE"

const newQuoteActionCreator = (quoteObject) => {
  return {
    type: NEW_QUOTE,
    payload: quoteObject
  };
};

const getNextQuoteReducer = (state = defaultState, action) => {
  switch (action.type) {
    case NEW_QUOTE:
       return {
         ...state,
         data: action.payload
       };
    default:
       return state;
  }
};

const store = Redux.createStore(getNextQuoteReducer);

const quotes = [
    {
        quoteText:"\"AAAAAA.\"",
        quoteAuthor:"BBBB",
    },
    {
        quoteText:"\"CCCCC.\"",
        quoteAuthor:"DDDD",
    }
];

反应位:

const QuoteBox = ({ text, author }) => { //destructuring
  return (
    <React.Fragment>
      <div className="quotable-square">
        <div className="content">
          <div id="text">{text}</div>
          <div id="author" className="author">{author}</div>
        </div>
      </div> 
    </React.Fragment>
  )
}

const Button = ({ onClick, title }) => {
   return (
      <button className="new-quote" onClick={onClick}>{title}</button>
   )
}

const App = (props) => {
  const [quote, setQuote] = React.useState(() => {
    const initialQuote = quotes[Math.floor(Math.random() * quotes.length)];
    return {
      data: initialQuote
    }
  });

  const chosenRandomQuoteToState = () => {
    let chosenQuote = randomQuoteFunction(quotes);
    props.selectNewQuote(chosenQuote);
  }

  return (
    <React.Fragment>
      <div className="container">
        <div id="quote-box">
          <QuoteBox text={(() => {
            switch (typeof props.currentQuote.data) {
              case "undefined":   return quote.data.quoteText 
              default:            return props.currentQuote.data.quoteText;
            }
          })()}/>
          <div className="actions">
            <Button id="new-quote" title="Get New Quote" onClick={chosenRandomQuoteToState} />
          </div>
        </div>    
      </div> 
    </React.Fragment>   
  )
}

反应Redux位:

const Provider = ReactRedux.Provider;

const mapStateToProps = (state) => {
  return {
    currentQuote: state
  }

const mapDispatchToProps = (dispatch) => {
    return {
        selectNewQuote: function(quoteToBeNewQuote) {
          dispatch(newQuoteActionCreator(quoteToBeNewQuote));
        }
    }
}

const connect = ReactRedux.connect

const Container = connect(mapStateToProps, mapDispatchToProps)(App);

const AppWrapper = () => {
    return (
      <Provider store= {store}>
        <Container />
      </Provider>
    );
};

ReactDOM.render(<AppWrapper />, document.getElementById('app'));

新手,所以对我好一点:)

2 个答案:

答案 0 :(得分:0)

您应该全力以赴,让redux管理当前报价的状态,而不是弄乱组件中的额外状态。由于您希望从一开始就在商店中选择随机报价,因此您可以在商店的初始状态中预先选择一个随机报价选择,或者将随机报价的选择作为一种效果进行调度,使其在安装时发生。这是后一种方法:

const App = (props) => {
  useEffect(() => {
    chosenRandomQuoteToState();
  }, []);

  const chosenRandomQuoteToState = () => {
    let chosenQuote = randomQuoteFunction(quotes);
    props.selectNewQuote(chosenQuote);
  };

  const currentQuote = props.currentQuote.data;

  return (
    <React.Fragment>
      <div className="container">
        <div id="quote-box">
          {currentQuote && <QuoteBox text={currentQuote}/>}
          <div className="actions">
            <Button id="new-quote" title="Get New Quote" onClick={chosenRandomQuoteToState} />
          </div>
        </div>    
      </div> 
    </React.Fragment>   
  )
}

答案 1 :(得分:0)

尝试这样的事情:

const initialState = {
  quotes: [
    {
      quoteText: '"AAAAAA."',
      quoteAuthor: 'BBBB',
    },
    {
      quoteText: '"CCCCC."',
      quoteAuthor: 'DDDD',
    },
  ],
}; //renamed defaultState

const mapStateToProps = state => {
  //state should hold data, container (map state) should
  //  create values based on that data
  const { quotes } = state;
  return {
    currentQuote:
      quotes[Math.floor(Math.random() * quotes.length)],
  };
};
const mapDispatchToProps = dispatch => ({
  selectNewQuote: dispatch(newQuoteActionCreator()),
});

const getNextQuoteReducer = (
  state = defaultState,
  action
) => {
  switch (action.type) {
    case NEW_QUOTE:
      return {
        ...state,
        quotes: [...state.quotes], //forces app container to re run
      };
    default:
      return state;
  }
};

并在您的操作中删除组件中的useState以及所有复杂的逻辑,该操作仅需要一种类型,而reducer将重新引用,因此App容器将重新运行并选择另一个随机引用。